क्या UIView की प्रतिलिपि बनाई जा सकती है?


81

बस इस तरह से उपयोग कर रहे हैं:

UIView* view2 = [view1 copy]; // view1 existed

इससे सिम्युलेटर इस ऐप को लॉन्च नहीं कर सकता है।

बनाए रखने का प्रयास करें,

UIView* view2 = [view1 retain]; // view1 existed
// modify view2 frame etc

किसी भी संशोधन पर view2लागू होगा view1, मैं समझता हूं कि view2उसी के साथ स्मृति साझा करें view1

UIViewकॉपी क्यों नहीं की जा सकती? क्या कारण है?

जवाबों:


33

आपका ऐप संभवतः कुछ के साथ क्रैश हो जाता है:

 [UIView copyWithZone:]: unrecognized selector sent to instance 0x1c6280

इसका कारण यह है कि यूआईवीईवाई नकल प्रोटोकॉल को लागू नहीं करता है, और इसलिए copyWithZoneयूआईवाइवाई में कोई चयनकर्ता नहीं है ।


10
UIView की प्रतिलिपि को लागू करने के लिए मुझे क्या करना चाहिए?
सत्यम

1
तो अगर आपके पास UIView का एक निश्चित संयोजन है और आप उस समय का उपयोग करना चाहते हैं, तो आपको ऐसे UIView को उप-वर्ग करना होगा?
अनाम सफेद

हाँ, वर्ग-स्तरीय फ़ैक्टरी विधियों के साथ उपवर्ग या श्रेणी जो उस दृश्य के पूर्वनिर्मित उदाहरणों को वापस करते हैं।
एंगिन कुरुतेपे

162

यह आपके लिए काम कर सकता है ... दृश्य को संग्रहीत करें और उसके बाद इसे अनारक्षित करें। इससे आपको एक दृश्य की गहरी प्रतिलिपि मिलनी चाहिए:

id copyOfView = 
[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];

1
यह एक हैक की तरह लगता है, लेकिन एक सपने की तरह काम करता है। ssj का उत्तर मूल रूप से एक 'कॉपी कंस्ट्रक्टर' है जो छोटे वर्गों के लिए ठीक है। आप शायद सभी संपत्तियों को एक साथ कॉपी करने के लिए obj-c रनटाइम का उपयोग कर सकते हैं .. यह अभी भी आसान है;)
पैट्रिक बोरोविक्ज़

1
यह काम करता है, लेकिन यहां तक ​​कि तुच्छ दृश्य पेड़ों के लिए बहुत धीमा लगता है।
इयान न्यूजन

6
यह काम करता है, लेकिन सावधान! यह @IBOutlets के लिए मान निर्धारित नहीं करता है, सभी "नकल" के बाद शून्य हैं
nalexn

1
ऐसा लगता है कि UIImageViews :(
इयूलियन ओनोफ्रेई जूल 28'15

1
धन्यवाद, महान काम करता है! ALSO कृपया ध्यान दें कि प्रतिलिपि किए गए दृश्य में कोई पर्यवेक्षक (माता-पिता) नहीं है, कोई अड़चन नहीं है और कोई इशारा पहचानने वाले नहीं हैं (यदि माता-पिता कोई भी नहीं हैं)।
१२:०२ पर सज्जोन

25

आप एक UIView एक्सटेंशन बना सकते हैं। उदाहरण के लिए नीचे दिए गए तेज़ स्निपेट में, फंक्शन copyView एक AnyObject देता है ताकि आप किसी UIView के किसी भी उपवर्ग को कॉपी कर सकें, अर्थात UIImageView। यदि आप केवल UIView की प्रतिलिपि बनाना चाहते हैं तो आप वापसी प्रकार को UIView में बदल सकते हैं।

//MARK: - UIView Extensions

    extension UIView
    {
       func copyView<T: UIView>() -> T {
            return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as! T
       }
    }

उदाहरण उपयोग:

let sourceView = UIView()
let copiedView = sourceView.copyView()

1
धन्यवाद, महान काम करता है! ALSO कृपया ध्यान दें कि प्रतिलिपि किए गए दृश्य में कोई पर्यवेक्षक (माता-पिता) नहीं है, कोई अड़चन नहीं है और कोई इशारा पहचानने वाले नहीं हैं (यदि माता-पिता कोई भी नहीं हैं)।
१२:०२ पर सज्जोन

6

स्विफ्ट 3.0.1 के लिए:

extension UIView{
 func copyView() -> AnyObject{
    return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! as AnyObject
 }
}

1

UIViewNSCopingप्रोटोकॉल को लागू नहीं करता है, UIView.h में घोषणा देखें :

@interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment>

इसलिए, यदि हम एक copyसमान विधि चाहते हैं, तो हमें NSCopingप्रोटोकॉल को एक श्रेणी में लागू करने की आवश्यकता है ।


-6

आप विधि कुछ इस तरह से बना सकते हैं:

-(UILabel*)copyLabelFrom:(UILabel*)label{
//add whatever needs to be copied
UILabel *newLabel = [[UILabel alloc]initWithFrame:label.frame];
newLabel.backgroundColor = label.backgroundColor;
newLabel.textColor = label.textColor;
newLabel.textAlignment = label.textAlignment;
newLabel.text = label.text;
newLabel.font = label.font;

return [newLabel autorelease];

}

फिर आप अपने आइवर को रिटर्न वैल्यू पर सेट कर सकते हैं और उसे ऐसे ही बनाए रख सकते हैं:

myLabel = [[self copyLabelFrom:myOtherLabel] retain];

14
यह सवाल का जवाब नहीं है।
ब्लूफ्लॉइड 8

1
क्या होगा अगर आपके लेबल में अन्य कस्टम पैरामीटर हैं जैसे नंबरऑफलाइन या टैग? क्या आप सभी प्रॉपर्टी सेट करेंगे?
Iirirzhan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.