UIView kopyalanabilir mi?


81

Basitçe bu şekilde kullanın:

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

Bu, simülatörün bu uygulamayı başlatamamasına neden olur.

Tutmayı deneyin,

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

Yapılacak her türlü değişiklik view2için geçerli olacaktır view1, bunu anlıyorum view2ile pay aynı bellek view1.

Neden UIViewkopyalanamıyor? Nedeni ne?

Yanıtlar:


33

Uygulamanız muhtemelen aşağıdaki gibi bir şeyle kilitleniyor:

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

Bunun nedeni, UIView'ın kopyalama protokolünü uygulamaması ve bu nedenle copyWithZoneUIView'de seçici olmamasıdır .


10
UIView kopyasını uygulamak için ne yapmalıyım?
— Satyam

1
Öyleyse, belirli bir UIView kombinasyonuna sahipseniz ve bunu birkaç kez kullanmak istiyorsanız, bu tür UIView'ı alt sınıflara ayırmanız gerekecek?
— Anonymous White

Evet, o görünümün önceden yapılandırılmış örneklerini döndüren sınıf düzeyinde fabrika yöntemleriyle alt sınıflandırma veya kategori.
— Engin Kurutepe

162

bu sizin için işe yarayabilir ... görünümü arşivleyin ve hemen ardından arşivden çıkarın. Bu size bir görünümün derin bir kopyasını vermelidir:

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

1
Bu biraz hileye benziyor ama bir rüya gibi çalışıyor. ssj'nin aşağıdaki cevabı temelde küçük sınıflar için uygun olan bir 'kopya yapıcı'dır. Tüm özellikleri bir kerede kopyalamak için belki obj-c çalışma zamanını kullanabilirsiniz .. Bu daha da kolay;)
— Patrick Borkowicz

1
Bu işe yarıyor, ancak önemsiz görünüm ağaçları için bile çok yavaş görünüyor.
— Ian Newson

6
Çalışıyor, ancak dikkatli olun! @IBOutlets için değerler ayarlamaz, "kopyalandıktan" sonra hepsi sıfırdır
— nalexn

1
Görünüşe göre UIImageViews :(
— Iulian Onofrei

1
Teşekkürler, harika çalışıyor! AYRICA, kopyalanan görünümün süpervizyon (üst), kısıtlama ve hareket tanıyıcı (ebeveyn varsa) olmadığını lütfen unutmayın.
— Sajjon

25

Bir UIView uzantısı oluşturabilirsiniz. Aşağıdaki örnek swift parçacığında, function copyView bir AnyObject döndürür, böylece bir UIView’ün herhangi bir alt sınıfını, yani UIImageView’u kopyalayabilirsiniz . Yalnızca UIV Görünümlerini kopyalamak istiyorsanız, dönüş türünü UIView olarak değiştirebilirsiniz.

//MARK: - UIView Extensions

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

Örnek kullanım:

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

1
Teşekkürler, harika çalışıyor! AYRICA, kopyalanan görünümün süpervizyon (üst), kısıtlama ve hareket tanıyıcı (ebeveyn varsa) olmadığını lütfen unutmayın.
— Sajjon

6

swift3.0.1 için:

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

1

UIViewNSCopingprotokolü uygulamaz, UIView.h'deki bildirime bakın :

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

Öyleyse, copybenzer bir yönteme sahip olmak istiyorsak , NSCopingprotokolü bir kategoride uygulamamız gerekir .


-6

Metodu şu şekilde yapabilirsiniz:

-(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];

}

Daha sonra ivarınızı dönüş değerine ayarlayabilir ve şu şekilde tutabilirsiniz:

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

14
bu soruya cevap vermiyor.
— bluefloyd8

1
etiketinizin numberOfLines veya tag gibi başka özel parametreleri varsa ne olur? Tüm özellikleri ayarlayacak mısınız?
— iamirzhan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.