UIView có thể được sao chép không?


81

Chỉ cần sử dụng theo cách này:

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

Điều này sẽ khiến trình mô phỏng không thể khởi chạy ứng dụng này.

Hãy thử giữ lại,

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

Bất kỳ sửa đổi nào view2sẽ áp dụng cho view1, tôi hiểu rằng view2chia sẻ cùng bộ nhớ với view1.

Tại sao không UIViewthể sao chép? Lý do là gì?

Câu trả lời:


33

Ứng dụng của bạn có thể gặp sự cố với những thứ như:

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

Lý do là UIView không triển khai giao thức sao chép, và do đó không có copyWithZonebộ chọn trong UIView.


10
Tôi nên làm gì để triển khai bản sao của UIView?
Satyam

1
Vì vậy, nếu bạn có một sự kết hợp nhất định của UIView và muốn sử dụng vài lần bạn sẽ cần phân lớp những UIView đó?
Anonymous White,

Có, phân lớp hoặc danh mục với các phương thức nhà máy cấp lớp trả về các thể hiện được định cấu hình trước của dạng xem đó.
Engin Kurutepe,

162

điều này có thể hiệu quả với bạn ... hãy lưu trữ chế độ xem và sau đó hủy lưu trữ nó ngay sau đó. Điều này sẽ cung cấp cho bạn một bản sao sâu về chế độ xem:

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

1
Điều đó có vẻ như một chút hack nhưng hoạt động như một giấc mơ. Câu trả lời của ssj dưới đây về cơ bản là một 'phương thức tạo bản sao' tốt cho các lớp nhỏ. Bạn có thể có thể sử dụng obj-c runtime để sao chép tất cả các thuộc tính cùng một lúc .. Đây là vẫn dễ dàng hơn;)
Patrick Borkowicz

1
Điều này hoạt động, nhưng dường như rất chậm đối với những cây có tầm nhìn tầm thường.
Ian Newson

6
Nó hoạt động, nhưng hãy cẩn thận! Nó không thiết lập giá trị cho @IBOutlets, tất cả chúng đều bằng không sau khi "sao chép"
nalexn

1
Điều này dường như bỏ qua UIImageViews :(
Iulian Onofrei

1
Cảm ơn, hoạt động tuyệt vời! CŨNG xin lưu ý rằng chế độ xem được sao chép không có superview (gốc), không có ràng buộc và không có trình nhận dạng cử chỉ (nếu chế độ chính có bất kỳ).
Sajjon

25

Bạn có thể tạo tiện ích mở rộng UIView. Trong đoạn mã nhanh ví dụ bên dưới, hàm copyView trả về một AnyObject để bạn có thể sao chép bất kỳ lớp con nào của một UIView, tức là UIImageView. Nếu bạn muốn sao chép chỉ UIViews bạn có thể thay đổi kiểu trả về để UIView.

//MARK: - UIView Extensions

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

Ví dụ sử dụng:

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

1
Cảm ơn, hoạt động tuyệt vời! CŨNG xin lưu ý rằng chế độ xem được sao chép không có superview (gốc), không có ràng buộc và không có trình nhận dạng cử chỉ (nếu chế độ chính có bất kỳ).
Sajjon

6

cho swift3.0.1:

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

1

UIViewkhông triển khai NSCopinggiao thức, hãy xem phần khai báo trong UIView.h :

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

Vì vậy, nếu chúng ta muốn có một copyphương thức like, chúng ta cần triển khai NSCopinggiao thức trong một danh mục hoặc lâu hơn.


-6

Bạn có thể thực hiện phương pháp như sau:

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

}

Sau đó, bạn có thể đặt ivar của mình thành giá trị trả về và giữ nguyên nó như sau:

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

14
điều này không trả lời câu hỏi.
bluefloyd8

1
điều gì sẽ xảy ra nếu nhãn của bạn có các thông số tùy chỉnh khác như numberOfLines hoặc thẻ? Bạn sẽ thiết lập tất cả các thuộc tính?
iamirzhan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.