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.