স্টোরিবোর্ড, কোড, টিপস এবং কয়েকটি গোছা
অন্যান্য উত্তরগুলি ঠিক আছে তবে এটি একটি সাম্প্রতিক উদাহরণ ব্যবহার করে অ্যানিমেটিং সীমাবদ্ধতার কয়েকটি মোটামুটি গুরুত্বপূর্ণ গ্যাচচাকে হাইলাইট করে। নিম্নলিখিতগুলি উপলব্ধি করার আগে আমি অনেকগুলি প্রকরণের মধ্য দিয়ে গিয়েছিলাম:
শক্তিশালী রেফারেন্স ধরে রাখতে আপনি ক্লাস ভেরিয়েবলগুলিতে লক্ষ্য করতে চান এমন প্রতিবন্ধকতা তৈরি করুন। সুইফটে আমি অলস ভেরিয়েবল ব্যবহার করেছি:
lazy var centerYInflection:NSLayoutConstraint = {
let temp = self.view.constraints.filter({ $0.firstItem is MNGStarRating }).filter ( { $0.secondItem is UIWebView }).filter({ $0.firstAttribute == .CenterY }).first
return temp!
}()
কিছু পরীক্ষা আমি লক্ষনীয় যে এক ভিউ থেকে বাধ্যতা প্রাপ্ত করা আবশ্যক উপরে (ওরফে superview) দুটি ভিউ যেখানে বাধ্যতা সংজ্ঞায়িত করা হয়। নীচের উদাহরণে (এমএনজিস্টাররেটিং এবং ইউআইউইউভিউ ভিউ উভয়ই আমি দুটি ধরণের আইটেমের মধ্যে সীমাবদ্ধতা তৈরি করছি এবং সেগুলি স্ব-ভিউয়ের মধ্যে সাবউভিউ রয়েছে)।
ফিল্টার চেইনিং
আমি স্যুইফ্টের ফিল্টার পদ্ধতির সুবিধা গ্রহণ করে কাঙ্ক্ষিত সীমাবদ্ধতা আলাদা করতে যা প্রতিস্থাপনের পয়েন্ট হিসাবে পরিবেশন করবে। একটি আরও জটিল হতে পারে তবে ফিল্টার এখানে দুর্দান্ত কাজ করে।
সুইফ্ট ব্যবহার করে অ্যানিমেশন সীমাবদ্ধতা
নোটা বেন - এই উদাহরণটি স্টোরিবোর্ড / কোড সমাধান এবং ধরে নেওয়া হয়েছে যে কেউ স্টোরিবোর্ডে ডিফল্ট সীমাবদ্ধতা তৈরি করেছে। এরপরে কোড ব্যবহার করে পরিবর্তনগুলি প্রাণবন্ত করা যায়।
ধরে নিচ্ছি যে আপনি সঠিক মানদণ্ডের সাথে ফিল্টার করার জন্য একটি সম্পত্তি তৈরি করেছেন এবং আপনার অ্যানিমেশনের জন্য একটি নির্দিষ্ট প্রতিস্থাপন পয়েন্টে পৌঁছাবেন (অবশ্যই যদি আপনি একাধিক সীমাবদ্ধতার প্রয়োজন হয় তবে আপনি একটি অ্যারের জন্য ফিল্টারও করতে পারেন)
lazy var centerYInflection:NSLayoutConstraint = {
let temp = self.view.constraints.filter({ $0.firstItem is MNGStarRating }).filter ( { $0.secondItem is UIWebView }).filter({ $0.firstAttribute == .CenterY }).first
return temp!
}()
....
একটু পরে...
@IBAction func toggleRatingView (sender:AnyObject){
let aPointAboveScene = -(max(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height) * 2.0)
self.view.layoutIfNeeded()
//Use any animation you want, I like the bounce in springVelocity...
UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.75, options: [.CurveEaseOut], animations: { () -> Void in
//I use the frames to determine if the view is on-screen
if CGRectContainsRect(self.view.frame, self.ratingView.frame) {
//in frame ~ animate away
//I play a sound to give the animation some life
self.centerYInflection.constant = aPointAboveScene
self.centerYInflection.priority = UILayoutPriority(950)
} else {
//I play a different sound just to keep the user engaged
//out of frame ~ animate into scene
self.centerYInflection.constant = 0
self.centerYInflection.priority = UILayoutPriority(950)
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
}) { (success) -> Void in
//do something else
}
}
}
অনেক ভুল পালা
এই নোটগুলি সত্যই টিপসের একটি সেট যা আমি নিজের জন্য লিখেছিলাম। আমি ব্যক্তিগতভাবে এবং বেদনাদায়ক সমস্ত করণীয় না করেছিলাম। আশা করি এই গাইড অন্যকে বাঁচাতে পারবে।
জেডপজিশনিংয়ের জন্য সতর্কতা অবলম্বন করুন। কখনও কখনও যখন দৃশ্যত কিছুই ঘটছে না তখন আপনার অন্যান্য ভিউগুলি লুকিয়ে রাখা উচিত বা আপনার অ্যানিমেটেড ভিউ সনাক্ত করতে ভিউ ডিবাগারটি ব্যবহার করা উচিত। এমনকি এমন কোনও ঘটনা আমি খুঁজে পেয়েছি যেখানে কোনও স্টোরবোর্ডের এক্সএমএল-তে ব্যবহারকারী সংজ্ঞায়িত রানটাইম অ্যাট্রিবিউট হারিয়ে গিয়েছিল এবং অ্যানিমেটেড ভিউটি কভার করা হয়েছিল (কাজ করার সময়)।
ডকুমেন্টেশন (নতুন এবং পুরানো), দ্রুত সহায়তা এবং শিরোনামগুলি পড়তে সর্বদা এক মিনিট সময় নিন। অ্যাপল অটোলআউট সীমাবদ্ধতাগুলি আরও ভালভাবে পরিচালনা করতে (স্ট্যাকের দেখুন দেখুন) অনেকগুলি পরিবর্তন করে রাখে। অথবা কমপক্ষে অটোলআউট কুকবুক । মনে রাখবেন যে কখনও কখনও সেরা সমাধানগুলি পুরানো ডকুমেন্টেশন / ভিডিওগুলিতে থাকে।
অ্যানিমেশনটিতে মানগুলি নিয়ে প্রায় খেলুন এবং অন্যান্য অ্যানিমেটডিউরডেরেশন ভেরিয়েন্টগুলি ব্যবহার করে বিবেচনা করুন।
অন্যান্য ধ্রুবকগুলিতে পরিবর্তনগুলি নির্ধারণের মানদণ্ড হিসাবে নির্দিষ্ট বিন্যাস মানগুলিকে হার্ডকোড করবেন না, পরিবর্তে এমন মানগুলি ব্যবহার করুন যা আপনাকে দেখার অবস্থান নির্ধারণ করতে দেয়। CGRectContainsRect
একটি উদাহরণ
- প্রয়োজনে সীমাবদ্ধতার সংজ্ঞাতে অংশ নেওয়া ভিউয়ের সাথে যুক্ত লেআউট মার্জিনটি ব্যবহার করতে দ্বিধা করবেন না
let viewMargins = self.webview.layoutMarginsGuide
: উদাহরণস্বরূপ
- আপনার যে কাজটি করতে হবে না এমন কাজ করবেন না, স্টোরিবোর্ডে সীমাবদ্ধতা সহ সমস্ত দর্শনগুলির সম্পত্তি হিসাবে স্ব-সংযুক্তি রয়েছে view
- যে কোনও প্রতিবন্ধকতার জন্য আপনার অগ্রাধিকারগুলি 1000 এরও কম পরিবর্তন করুন I আমি স্টোরিবোর্ডে আমার 250 (নিম্ন) বা 750 (উচ্চ) তে সেট করেছি; (যদি আপনি কোডের যে কোনও কিছুতে 1000 টি অগ্রাধিকার পরিবর্তন করার চেষ্টা করেন তবে অ্যাপ্লিকেশনটি ক্রাশ হবে কারণ 1000 প্রয়োজন)
- তাত্ক্ষণিকভাবে অ্যাক্টিভেট কনস্ট্রেন্টস এবং নিষ্ক্রিয়করণ কনট্রেনটগুলি ব্যবহার করার চেষ্টা না করার বিষয়টি বিবেচনা করুন (তাদের জায়গা রয়েছে তবে কেবল শিখতে গিয়ে বা আপনি যদি কোনও স্টোরিবোর্ড ব্যবহার করছেন সম্ভবত এটি আপনার অত্যধিক কাজ করার অর্থ রয়েছে - নীচে যেমন দেখানো হয়েছে তবুও তাদের একটি জায়গা রয়েছে)
- আপনি যদি কোডটিতে সত্যিকার অর্থে একটি নতুন বাধা না যোগ করেন তবে অ্যাডকন্ট্রেন্টস / রিমুভ কনট্রেন্টগুলি ব্যবহার না করার বিষয়টি বিবেচনা করুন। আমি দেখতে পেলাম যে বেশিরভাগ সময় আমি স্টোরিবোর্ডে পছন্দসই সীমাবদ্ধতাগুলি দিয়ে দেখি (ভিউটি অফস্ক্রিন স্থাপন করে), তারপরে কোডে, স্টোরিবোর্ডে পূর্বে তৈরি হওয়া সীমাবদ্ধতাগুলিকে ঘুরিয়ে দেওয়ার জন্য আমি সঞ্চার করি।
- আমি নতুন এনএসএনচরলআউট ক্লাস এবং সাবক্লাসগুলির সাথে সীমাবদ্ধতা তৈরি করতে প্রচুর অপচয় করার সময় ব্যয় করেছি। এই কাজগুলি ঠিকঠাক তবে এটি বুঝতে আমার কিছুটা সময় লেগেছিল যে আমার যে সমস্ত প্রতিবন্ধকতাগুলির প্রয়োজন ছিল সেগুলি স্টোরবোর্ডে ইতিমধ্যে বিদ্যমান। আপনি যদি কোডটিতে সীমাবদ্ধতা তৈরি করেন তবে অবশ্যই আপনার সীমাবদ্ধতাগুলিকে একত্রিত করতে এই পদ্ধতিটি ব্যবহার করুন:
স্টোরিবোর্ডগুলি ব্যবহার করার সময় AVOID এর সমাধানের দ্রত নমুনা
private var _nc:[NSLayoutConstraint] = []
lazy var newConstraints:[NSLayoutConstraint] = {
if !(self._nc.isEmpty) {
return self._nc
}
let viewMargins = self.webview.layoutMarginsGuide
let minimumScreenWidth = min(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height)
let centerY = self.ratingView.centerYAnchor.constraintEqualToAnchor(self.webview.centerYAnchor)
centerY.constant = -1000.0
centerY.priority = (950)
let centerX = self.ratingView.centerXAnchor.constraintEqualToAnchor(self.webview.centerXAnchor)
centerX.priority = (950)
if let buttonConstraints = self.originalRatingViewConstraints?.filter({
($0.firstItem is UIButton || $0.secondItem is UIButton )
}) {
self._nc.appendContentsOf(buttonConstraints)
}
self._nc.append( centerY)
self._nc.append( centerX)
self._nc.append (self.ratingView.leadingAnchor.constraintEqualToAnchor(viewMargins.leadingAnchor, constant: 10.0))
self._nc.append (self.ratingView.trailingAnchor.constraintEqualToAnchor(viewMargins.trailingAnchor, constant: 10.0))
self._nc.append (self.ratingView.widthAnchor.constraintEqualToConstant((minimumScreenWidth - 20.0)))
self._nc.append (self.ratingView.heightAnchor.constraintEqualToConstant(200.0))
return self._nc
}()
আপনি যদি এই টিপসগুলির একটি বা আরও সাধারণ বিষয়গুলি ভুলে যান তবে লেফটটি আইফনপিডটি কোথায় যুক্ত করতে চান তবে সম্ভবত কিছুই ঘটবে না: সেক্ষেত্রে আপনার অর্ধ বেকড সমাধান থাকতে পারে:
এনবি - নীচে অটোলআউট বিভাগ এবং মূল গাইডটি পড়তে কিছুক্ষণ সময় নিন। আপনার গতিশীল অ্যানিমেটারগুলির পরিপূরক করতে এই কৌশলগুলি ব্যবহার করার একটি উপায় রয়েছে।
UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.3, initialSpringVelocity: 1.0, options: [.CurveEaseOut], animations: { () -> Void in
//
if self.starTopInflectionPoint.constant < 0 {
//-3000
//offscreen
self.starTopInflectionPoint.constant = self.navigationController?.navigationBar.bounds.height ?? 0
self.changeConstraintPriority([self.starTopInflectionPoint], value: UILayoutPriority(950), forView: self.ratingView)
} else {
self.starTopInflectionPoint.constant = -3000
self.changeConstraintPriority([self.starTopInflectionPoint], value: UILayoutPriority(950), forView: self.ratingView)
}
}) { (success) -> Void in
//do something else
}
}
অটোলআউট গাইড থেকে স্নিপেট (দ্বিতীয় স্নিপেটটি ওএস এক্স ব্যবহারের জন্য নোট করুন)। বিটিডাব্লু - এটি যতদূর আমি দেখতে পাচ্ছি বর্তমান গাইডে আর নেই। পছন্দসই কৌশলগুলি বিকশিত হতে থাকে।
অটো লেআউট দ্বারা তৈরি অ্যানিমেটিং পরিবর্তনগুলি
অটো লেআউট দ্বারা করা অ্যানিমেটরিং পরিবর্তনগুলির উপরে যদি আপনার পুরো নিয়ন্ত্রণের প্রয়োজন হয় তবে আপনাকে অবশ্যই নিজের বাধা পরিবর্তন করতে হবে প্রোগ্রামিয়ালি। আইওএস এবং ওএস এক্স উভয়ের ক্ষেত্রে প্রাথমিক ধারণাটি একই, তবে কয়েকটি ছোটখাটো পার্থক্য রয়েছে।
কোনও আইওএস অ্যাপ্লিকেশনে, আপনার কোডটি নীচের মতো কিছু দেখাচ্ছে:
[containerView layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0 animations:^{
// Make all constraint changes here
[containerView layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];
ওএস এক্স-এ, স্তর-ব্যাকযুক্ত অ্যানিমেশনগুলি ব্যবহার করার সময় নিম্নলিখিত কোডটি ব্যবহার করুন:
[containterView layoutSubtreeIfNeeded];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
[context setAllowsImplicitAnimation: YES];
// Make all constraint changes here
[containerView layoutSubtreeIfNeeded];
}];
আপনি যখন স্তর-ব্যাকযুক্ত অ্যানিমেশন ব্যবহার করছেন না, তখন আপনাকে অবশ্যই সীমাবদ্ধতার অ্যানিম্যাটর ব্যবহার করে ধ্রুবকটি অ্যানিমেট করতে হবে:
[[constraint animator] setConstant:42];
যারা আরও ভালভাবে শিখেন তাদের জন্য অ্যাপল থেকে এই প্রাথমিক ভিডিওটি দেখুন ।
গভীর মনোযোগ দাও
ডকুমেন্টেশনে প্রায়শই ছোট ছোট নোট বা কোডের টুকরা থাকে যা বড় আইডিয়াগুলিতে নিয়ে যায়। উদাহরণস্বরূপ গতিশীল অ্যানিমেটারগুলিতে অটো লেআউট সীমাবদ্ধতা যুক্ত করা একটি বড় ধারণা।
শুভকামনা এবং বাহিনী আপনার সাথে থাকুক।