উত্তর:
উত্তরটি এখানে দেওয়া হয়েছে, এটি আমার উত্তর এবং কৃষ্ণণের মিশ্রণ।
cabasicanimation.fillMode = kCAFillModeForwards;
cabasicanimation.removedOnCompletion = NO;
ডিফল্ট মান kCAFillModeRemoved
। (আপনি যে রিসেট আচরণটি দেখছেন তা কী।)
অপসারণযুক্ত সমস্যাটি হল ইউআই উপাদানটি ব্যবহারকারীর ইন্টারঅ্যাকশনকে মঞ্জুরি দেয় না।
আমি কৌশলটি হ'ল অ্যানিমেশনটিতে FROM মান এবং অবজেক্টে TO মান সেট করা। অ্যানিমেশনটি শুরুর আগে TO মানটি স্বয়ংক্রিয়ভাবে পূরণ করবে এবং এটি সরিয়ে ফেলা হলে অবজেক্টটিকে তার সঠিক অবস্থানে ছেড়ে দেবে।
// fade in
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath: @"opacity"];
alphaAnimation.fillMode = kCAFillModeForwards;
alphaAnimation.fromValue = NUM_FLOAT(0);
self.view.layer.opacity = 1;
[self.view.layer addAnimation: alphaAnimation forKey: @"fade"];
alphaAnimation.beginTime = 1;
, fillMode
আমি যতদূর বলতে পারি প্রয়োজনের প্রয়োজন নেই ...?
beginTime
এটি আপেক্ষিক নয়, আপনার যেমন ব্যবহার করা উচিত:CACurrentMediaTime()+1;
fillMode
, আরও স্পষ্টভাবে CAAnimations ব্যবহার করার সময় মূল মানগুলিতে ফিরে যাওয়া থেকে আটকাতে আরও দেখুন
নিম্নলিখিত সম্পত্তি সেট করুন:
animationObject.removedOnCompletion = NO;
এটি আপনার কোডের ভিতরে রাখুন
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.fillMode = kCAFillModeForwards;
theGroup.removedOnCompletion = NO;
আপনি যখন এটিকে স্তরটিতে যুক্ত CABasicAnimation
করবেন position
তখন আপনি কীটির কী সেট করতে পারবেন । এটি করে এটি রান লুপের বর্তমান পাসের পজিশনে সম্পন্ন অন্তর্নিহিত অ্যানিমেশনটিকে ওভাররাইড করবে।
CGFloat yOffset = 30;
CGPoint endPosition = CGPointMake(someLayer.position.x,someLayer.position.y + yOffset);
someLayer.position = endPosition; // Implicit animation for position
CABasicAnimation * animation =[CABasicAnimation animationWithKeyPath:@"position.y"];
animation.fromValue = @(someLayer.position.y);
animation.toValue = @(someLayer.position.y + yOffset);
[someLayer addAnimation:animation forKey:@"position"]; // The explicit animation 'animation' override implicit animation
আপনার কাছে 2011 অ্যাপল ডাব্লুডাব্লুডিসি ভিডিও সেশন 421 - কোর অ্যানিমেশন প্রয়োজনীয়তা (ভিডিওর মাঝামাঝি) সম্পর্কিত আরও তথ্য থাকতে পারে
someLayer.position = endPosition;
। এবং ডাব্লুডাব্লুডিসিতে রেফের জন্য ধন্যবাদ!
একটি কালায়ারের একটি মডেল স্তর এবং উপস্থাপনা স্তর থাকে। একটি অ্যানিমেশন চলাকালীন, উপস্থাপনা স্তরটি মডেলটির থেকে স্বাধীনভাবে আপডেট হয়। অ্যানিমেশনটি সম্পূর্ণ হয়ে গেলে, উপস্থাপনা স্তরটি মডেল থেকে মান সহ আপডেট করা হয়। অ্যানিমেশনটি শেষ হওয়ার পরে যদি আপনি কোনও ঝাঁকুনি দেওয়া লাফ এড়াতে চান তবে কীটি হ'ল দুটি স্তরকে সিঙ্ক করে রাখা।
যদি আপনি শেষ মানটি জানেন তবে আপনি সরাসরি মডেলটি সেট করতে পারেন।
self.view.layer.opacity = 1;
তবে আপনার যদি এমন অ্যানিমেশন থাকে যেখানে আপনি শেষ অবস্থানটি জানেন না (উদাহরণস্বরূপ একটি ধীর বিবর্ণ যা ব্যবহারকারী বিরতি দিতে পারে এবং তারপরে বিপরীত হতে পারে), তবে আপনি বর্তমান মানটি সন্ধানের জন্য সরাসরি উপস্থাপনা স্তরটি জিজ্ঞাসা করতে পারেন, এবং তারপরে মডেলটি আপডেট করুন।
NSNumber *opacity = [self.layer.presentationLayer valueForKeyPath:@"opacity"];
[self.layer setValue:opacity forKeyPath:@"opacity"];
উপস্থাপনা স্তর থেকে মানটি টানানো বিশেষত স্কেলিং বা ঘূর্ণন কীপ্যাথগুলির জন্যও কার্যকর। (যেমন transform.scale
, transform.rotation
)
ব্যবহার না করে removedOnCompletion
আপনি এই কৌশলটি চেষ্টা করতে পারেন:
self.animateOnX(item: shapeLayer)
func animateOnX(item:CAShapeLayer)
{
let endPostion = CGPoint(x: 200, y: 0)
let pathAnimation = CABasicAnimation(keyPath: "position")
//
pathAnimation.duration = 20
pathAnimation.fromValue = CGPoint(x: 0, y: 0)//comment this line and notice the difference
pathAnimation.toValue = endPostion
pathAnimation.fillMode = kCAFillModeBoth
item.position = endPostion//prevent the CABasicAnimation from resetting item's position when the animation finishes
item.add(pathAnimation, forKey: nil)
}
সুতরাং আমার সমস্যাটি হ'ল আমি প্যানের অঙ্গভঙ্গিতে কোনও বস্তুর ঘোরানোর চেষ্টা করছিলাম এবং তাই প্রতিটি পদক্ষেপে আমার একাধিক অভিন্ন অ্যানিমেশন ছিল। আমার উভয় ছিল fillMode = kCAFillModeForwards
এবং isRemovedOnCompletion = false
এটি কোনও উপকারে আসেনি। আমার ক্ষেত্রে, আমাকে নিশ্চিত করতে হয়েছিল যে আমি যখনই নতুন অ্যানিমেশন যুক্ত করি তখন অ্যানিমেশন কীটি আলাদা হয় :
let angle = // here is my computed angle
let rotate = CABasicAnimation(keyPath: "transform.rotation.z")
rotate.toValue = angle
rotate.duration = 0.1
rotate.isRemovedOnCompletion = false
rotate.fillMode = CAMediaTimingFillMode.forwards
head.layer.add(rotate, forKey: "rotate\(angle)")
সহজভাবে সেট করা fillMode
এবং removedOnCompletion
আমার জন্য কাজ করে না। আমি নীচের সমস্ত বৈশিষ্ট্যকে CabasicAnimation অবজেক্টে সেট করে সমস্যার সমাধান করেছি :
CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"];
ba.duration = 0.38f;
ba.fillMode = kCAFillModeForwards;
ba.removedOnCompletion = NO;
ba.autoreverses = NO;
ba.repeatCount = 0;
ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.85f, 0.85f, 1.0f)];
[myView.layer addAnimation:ba forKey:nil];
এই কোডটি myView
এর আকারের 85% (তৃতীয় মাত্রা আনলটার্ড) এ রূপান্তরিত করে।
কোর অ্যানিমেশন দুটি স্তরের স্তরক্রম বজায় রাখে: মডেল স্তর এবং উপস্থাপনা স্তর । যখন অ্যানিমেশনটি চলছে, মডেল স্তরটি আসলে অক্ষত থাকে এবং এটি প্রাথমিক মান রাখে initial ডিফল্টরূপে, অ্যানিমেশনটি শেষ হয়ে গেলে এটি সরিয়ে ফেলা হয়। তারপরে উপস্থাপনা স্তরটি মডেল স্তরের মানটিতে ফিরে আসে।
সহজভাবে সেট removedOnCompletion
করার NO
অর্থ অ্যানিমেশনটি সরানো হবে না এবং মেমরির অপচয় করবে। তদ্ব্যতীত, মডেল স্তর এবং উপস্থাপনা স্তর আর সিঙ্ক্রোনাস হবে না, যা সম্ভাব্য বাগগুলি নিয়ে যেতে পারে।
সুতরাং মডেল স্তরটিতে সরাসরি চূড়ান্ত মানটিতে সম্পত্তি আপডেট করা আরও ভাল সমাধান হবে।
self.view.layer.opacity = 1;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = 0;
animation.toValue = 1;
[self.view.layer addAnimation:animation forKey:nil];
উপরের কোডের প্রথম লাইনের ফলে যদি কোনও অন্তর্নিহিত অ্যানিমেশন থাকে তবে তা বন্ধ করার চেষ্টা করুন:
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.view.layer.opacity = 1;
[CATransaction commit];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = 0;
animation.toValue = 1;
[self.view.layer addAnimation:animation forKey:nil];
এইটা কাজ করে:
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 0.3
someLayer.opacity = 1 // important, this is the state you want visible after the animation finishes.
someLayer.addAnimation(animation, forKey: "myAnimation")
কোর অ্যানিমেশন অ্যানিমেশন চলাকালীন আপনার স্বাভাবিক স্তরটির উপরে একটি 'উপস্থাপনা স্তর' দেখায়। সুতরাং অ্যানিমেশনটি শেষ হয়ে গেলে এবং উপস্থাপনা স্তরটি চলে গেলে আপনি যা দেখতে চান তাতে অস্বচ্ছতা (বা যাই হোক না কেন) সেট করুন। ফ্লিকারটি সম্পূর্ণ হয়ে গেলে এড়ানোর জন্য অ্যানিমেশনটি যুক্ত করার আগে লাইনে এটি করুন।
আপনি যদি দেরি করতে চান তবে নিম্নলিখিতটি করুন:
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 0.3
animation.beginTime = someLayer.convertTime(CACurrentMediaTime(), fromLayer: nil) + 1
animation.fillMode = kCAFillModeBackwards // So the opacity is 0 while the animation waits to start.
someLayer.opacity = 1 // <- important, this is the state you want visible after the animation finishes.
someLayer.addAnimation(animation, forKey: "myAnimation")
পরিশেষে, আপনি যদি 'মুছে ফেলা অফকম্পশন = মিথ্যা' ব্যবহার করেন তবে স্তরটি নিষ্পত্তি না হওয়া অবধি এটি সিএএনিমেশনগুলি ফাঁস করবে - এড়িয়ে চলুন।
@ লেসলি গডউইনের উত্তরটি সত্যিই ভাল নয়, "সেল্ফ.ভিউ.লেয়ার.ওপ্যাসিটি = 1;" তাত্ক্ষণিকভাবে সম্পন্ন করা হয় (এটি প্রায় এক সেকেন্ড সময় নেয়), যদি আপনার সন্দেহ থাকে তবে দয়া করে alphaAnimation.duration 10.0 এ স্থির করুন। আপনাকে এই লাইনটি সরিয়ে ফেলতে হবে।
সুতরাং, আপনি যখন কেসিএফিলমোডফোরওয়ার্ডে ফিলমোড ঠিক করেন এবং কোনটিতে কমপ্লিট সরিয়ে ফেলেন, আপনি অ্যানিমেশনটি স্তরটিতে থেকে যেতে দিন। আপনি যদি অ্যানিমেশন প্রতিনিধি ঠিক করেন এবং এর মতো কিছু চেষ্টা করেন:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[theLayer removeAllAnimations];
}
... আপনি এই লাইনটি কার্যকর করার মুহুর্তে স্তরটি তত্ক্ষণাত পুনরুদ্ধার করে। এটি আমরা এড়াতে চেয়েছিলাম।
এটিকে থেকে অ্যানিমেশনটি সরানোর আগে আপনাকে অবশ্যই স্তর সম্পত্তিটি ঠিক করতে হবে। এটা চেষ্টা কর:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if([anim isKindOfClass:[CABasicAnimation class] ]) // check, because of the cast
{
CALayer *theLayer = 0;
if(anim==[_b1 animationForKey:@"opacity"])
theLayer = _b1; // I have two layers
else
if(anim==[_b2 animationForKey:@"opacity"])
theLayer = _b2;
if(theLayer)
{
CGFloat toValue = [((CABasicAnimation*)anim).toValue floatValue];
[theLayer setOpacity:toValue];
[theLayer removeAllAnimations];
}
}
}
দেখে মনে হচ্ছে মুছে ফেলা অনকম্পশন পতাকাটি মিথ্যাতে সেট হয়েছে এবং ফিলিপড কেসিএফিলমোড ফরওয়ার্ডে সেট করে আমার পক্ষেও কাজ করে না।
আমি একটি স্তরে নতুন অ্যানিমেশন প্রয়োগ করার পরে, একটি অ্যানিমেটিং বস্তু তার প্রাথমিক অবস্থায় পুনরায় সেট করে এবং তারপরে সেই অবস্থা থেকে অ্যানিমেট করে। অতিরিক্তভাবে যা করতে হবে তা হ'ল নতুন অ্যানিমেশন সেট করার আগে মডেল স্তরের পছন্দসই সম্পত্তিটিকে তার উপস্থাপনা স্তরের সম্পত্তি অনুযায়ী সেট করা:
someLayer.path = ((CAShapeLayer *)[someLayer presentationLayer]).path;
[someLayer addAnimation:someAnimation forKey:@"someAnimation"];
অন্তর্নিহিত অ্যানিমেশনগুলি ব্যবহার করা সবচেয়ে সহজ সমাধান। এটি আপনার জন্য সমস্ত সমস্যার সমাধান করবে:
self.layer?.backgroundColor = NSColor.red.cgColor;
যদি আপনি যেমন সময়কাল কাস্টমাইজ করতে চান তবে আপনি এটি ব্যবহার করতে পারেন NSAnimationContext
:
NSAnimationContext.beginGrouping();
NSAnimationContext.current.duration = 0.5;
self.layer?.backgroundColor = NSColor.red.cgColor;
NSAnimationContext.endGrouping();
দ্রষ্টব্য: এটি কেবল ম্যাকস-এ পরীক্ষিত।
এটি করার সময় আমি প্রাথমিকভাবে কোনও অ্যানিমেশন দেখিনি। সমস্যাটি হ'ল ভিউ-ব্যাকড লেয়ারের স্তরটি অ্যানিমেটকে অন্তর্ভুক্ত করে না । এটি সমাধান করার জন্য, আপনি নিজেই একটি স্তর যুক্ত করেছেন তা নিশ্চিত করুন (স্তরটিকে ব্যাক-তে-সেট করার আগে)।
এটি কীভাবে করা যায় তার একটি উদাহরণ হ'ল:
override func awakeFromNib() {
self.layer = CALayer();
//self.wantsLayer = true;
}
ব্যবহার করে self.wantsLayer
আমার পরীক্ষায় কোনও পার্থক্য হয়নি, তবে এর কিছু পার্শ্ব প্রতিক্রিয়া থাকতে পারে যা আমি জানি না।
খেলার মাঠের একটি নমুনা এখানে:
import PlaygroundSupport
import UIKit
let resultRotation = CGFloat.pi / 2
let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 200.0, height: 300.0))
view.backgroundColor = .red
//--------------------------------------------------------------------------------
let rotate = CABasicAnimation(keyPath: "transform.rotation.z") // 1
rotate.fromValue = CGFloat.pi / 3 // 2
rotate.toValue = resultRotation // 3
rotate.duration = 5.0 // 4
rotate.beginTime = CACurrentMediaTime() + 1.0 // 5
// rotate.isRemovedOnCompletion = false // 6
rotate.fillMode = .backwards // 7
view.layer.add(rotate, forKey: nil) // 8
view.layer.setAffineTransform(CGAffineTransform(rotationAngle: resultRotation)) // 9
//--------------------------------------------------------------------------------
PlaygroundPage.current.liveView = view
false
করার isRemovedOnCompletion
- কোর অ্যানিমেশন পরিষ্কার দিন পর অ্যানিমেশন সমাপ্ত হয়
.presentation()
"চূড়ান্ত, দেখা" মান পেতে তাকান । নীচের সঠিক উত্তরগুলির জন্য অনুসন্ধান করুন যা উপস্থাপনা স্তরটি দিয়ে এটি সম্পন্ন করে ব্যাখ্যা করে।