আমি সর্বদা "এটিকে একটি সাবউইউ হিসাবে যুক্ত করুন" সমাধানটি অসন্তুষ্টির সাথে খুঁজে পেয়েছি, এটি দেখতে (1) অটোলেআউট, (2) @IBInspectableএবং (3) আউটলেটগুলির সাথে স্ক্রু হিসাবে রয়েছে । পরিবর্তে, আমি আপনাকে যাদু awakeAfter:, একটি NSObjectপদ্ধতির সাথে পরিচয় করিয়ে দিন ।
awakeAfterআপনাকে কোনও এনআইবি / স্টোরিবোর্ড থেকে সম্পূর্ণ আলাদাভাবে আলাদাভাবে অবজেক্টটি জাগিয়ে তুলতে দেয়। সেই অবজেক্টটি হাইড্রেশন প্রক্রিয়াটির মধ্য দিয়ে রাখা হয়, এটির জন্য awakeFromNibআহ্বান জানানো হয়, ভিউ হিসাবে যোগ করা হয় ইত্যাদি
আমরা এটিকে আমাদের দৃশ্যের একটি "কার্ডবোর্ড কাট-আউট" সাবক্লাসে ব্যবহার করতে পারি, যার একমাত্র উদ্দেশ্য NIB থেকে ভিউ লোড করা এবং স্টোরিবোর্ডে ব্যবহারের জন্য এটি ফিরিয়ে দেওয়া হবে। এম্বেডযোগ্য সাবক্লাসটি তারপরে মূল শ্রেণীর চেয়ে স্টোরিবোর্ড দর্শনের পরিচয় পরিদর্শকটিতে নির্দিষ্ট করা থাকে। এটি কাজ করার জন্য এটি আসলে একটি সাবক্লাস হতে হবে না, তবে এটি একটি সাবক্লাস তৈরি করে যা আইবি কোনও আইবিআইস্পেসটেবল / আইবিআউটলেট বৈশিষ্ট্য দেখতে দেয় see
এই অতিরিক্ত বয়লারপ্লেটটি আপোস্টিমাল মনে হতে পারে। এবং এক অর্থে এটি হ'ল, কারণ আদর্শভাবে এটি নির্বিঘ্নে UIStoryboardপরিচালনা করবে — তবে এটির মূল এনআইবি এবং UIViewসাবক্লাসটি সম্পূর্ণরূপে অবিস্মরণিত রেখে দেওয়ার সুবিধা রয়েছে । এটি যে ভূমিকা পালন করে তা মূলত একটি অ্যাডাপ্টার বা সেতু বর্গের এবং এটি আফসোসযোগ্য হলেও পুরোপুরি বৈধ, ডিজাইন-ভিত্তিক, অতিরিক্ত শ্রেণি হিসাবে। ফ্লিপ দিকে, আপনি যদি আপনার ক্লাসগুলির সাথে পার্সোনমনীয় হতে পছন্দ করেন তবে @ বেনপ্যাচের সমাধান অন্যান্য কিছু ছোটখাটো পরিবর্তনগুলি সহ একটি প্রোটোকল প্রয়োগ করে কাজ করে। কোন সমাধানটির প্রশ্নটি প্রোগ্রামার শৈলীর বিষয়ে আরও ভালভাবে ফুটে উঠেছে: কোনওটি বস্তুর রচনা বা একাধিক উত্তরাধিকারকে পছন্দ করে কিনা।
দ্রষ্টব্য: NIB ফাইলে ভিউতে শ্রেণীর সেটটি একই রয়েছে। এম্বেডযোগ্য উপশ্রেণী হয় শুধুমাত্র স্টোরিবোর্ড ব্যবহার করা হয়। সাবক্লাসটি কোডে দর্শনটি ইনস্ট্যান্ট করতে ব্যবহার করা যাবে না, সুতরাং এটির কোনও অতিরিক্ত যুক্তি নিজেই থাকা উচিত নয়। এটিতে কেবলawakeAfter হুক থাকা উচিত ।
class MyCustomEmbeddableView: MyCustomView {
override func awakeAfter(using aDecoder: NSCoder) -> Any? {
return (UIView.instantiateViewFromNib("MyCustomView") as MyCustomView?)! as Any
}
}
Here এখানে একটি উল্লেখযোগ্য ব্যর্থতা হ'ল আপনি যদি স্টোরিবোর্ডে প্রস্থ, উচ্চতা বা দিক অনুপাতের সীমাবদ্ধতাগুলি সংজ্ঞায়িত করেন যা অন্য দৃশ্যের সাথে সম্পর্কিত নয় তবে সেগুলি ম্যানুয়ালি অনুলিপি করতে হবে। দুটি মতামত সম্পর্কিত সীমাবদ্ধতাগুলি নিকটতম সাধারণ পূর্বপুরুষের উপর ইনস্টল করা হয় এবং স্টোরিবোর্ডটি অভ্যন্তরীণ আউট থেকে জাগ্রত হয়, সুতরাং ততক্ষণে তত্ত্বাবধানে এই সীমাবদ্ধতাগুলি হাইড্রেটেড হওয়ার সাথে সাথে অদলবদল ইতিমধ্যে ঘটেছে। যে প্রশ্নগুলিতে কেবলমাত্র প্রশ্নের মধ্যে জড়িত রয়েছে সেগুলি সরাসরি সেই দৃশ্যে ইনস্টল করা হয় এবং সুতরাং অনুলিপিটি অনুলিপি না করা হলে টাস্ক হয়ে যায়।
নোট করুন যে এখানে যা ঘটছে তা হ'ল স্টোরিবোর্ডে দৃশ্যে ইনস্টল হওয়া সীমাবদ্ধতাগুলি নতুন তাত্ক্ষণিক দৃশ্যে অনুলিপি করা হয়েছে , যার ইতিমধ্যে নিজস্ব সীমাবদ্ধতা থাকতে পারে, এটি তার নীব ফাইলটিতে সংজ্ঞায়িত করা হয়েছে। এগুলি ক্ষতিগ্রস্থ হয়।
class MyCustomEmbeddableView: MyCustomView {
override func awakeAfter(using aDecoder: NSCoder) -> Any? {
let newView = (UIView.instantiateViewFromNib("MyCustomView") as MyCustomView?)!
for constraint in constraints {
if constraint.secondItem != nil {
newView.addConstraint(NSLayoutConstraint(item: newView, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: newView, attribute: constraint.secondAttribute, multiplier: constraint.multiplier, constant: constraint.constant))
} else {
newView.addConstraint(NSLayoutConstraint(item: newView, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: constraint.constant))
}
}
return newView as Any
}
}
instantiateViewFromNibএটিতে টাইপ-সেফ এক্সটেনশন UIView। এটি সমস্ত কিছুই NIB এর অবজেক্টগুলির মধ্যে লুপ হয় যতক্ষণ না এটি ধরণের সাথে মিলে যায় finds নোট করুন যে জেনেরিক টাইপটি হ'ল রিটার্ন মান, সুতরাং টাইপটি কল সাইটে নির্দিষ্ট করতে হবে।
extension UIView {
public class func instantiateViewFromNib<T>(_ nibName: String, inBundle bundle: Bundle = Bundle.main) -> T? {
if let objects = bundle.loadNibNamed(nibName, owner: nil) {
for object in objects {
if let object = object as? T {
return object
}
}
}
return nil
}
}