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

그 이유는 UIView는 복사 프로토콜을 구현하지 않기 때문에 copyWithZoneUIView에 선택기 가 없기 때문입니다 .


10
UIView 사본을 구현하려면 어떻게해야합니까?
— 사티 암

1
따라서 UIView의 특정 조합이 있고이를 여러 번 사용하려면 이러한 UIView를 하위 클래스로 만들어야합니까?
— 익명 화이트

예, 해당 뷰의 사전 구성된 인스턴스를 반환하는 클래스 수준 팩토리 메서드가있는 하위 클래스 또는 범주.
— Engin Kurutepe 2012 년

162

이것은 당신을 위해 일할 수 있습니다 ...보기를 보관하고 바로 보관을 취소하십시오. 이것은 당신에게 뷰의 깊은 사본을 줄 것입니다 :

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

1
약간의 해킹처럼 보이지만 꿈처럼 작동합니다. 아래 ssj의 대답은 기본적으로 작은 클래스에 적합한 '복사 생성자'입니다. 당신은 어쩌면이 여전히 쉽게 .. 한 번에 모든 속성을 복사 할 OBJ-C 런타임을 사용할 수 있습니다)
— 패트릭 Borkowicz

1
이것은 작동하지만 사소한 뷰 트리에서도 매우 느린 것 같습니다.
— Ian Newson 2014

6
작동하지만 조심하십시오! 그것은 그들 모두가 "복사"이후 전무, @IBOutlets에 대한 값을 설정하지 않습니다
— nalexn

1
이것은 무시하는 것 같다 UIImageView의 :(
— 울리 Onofrei

1
감사합니다. 잘 작동합니다! 또한 복사 된 뷰에는 수퍼 뷰 (부모), 제약 조건 및 제스처 인식기 (부모에있는 경우)가 없습니다.
— Sajjon

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
감사합니다. 잘 작동합니다! 또한 복사 된 뷰에는 수퍼 뷰 (부모), 제약 조건 및 제스처 인식기 (부모에있는 경우)가 없습니다.
— Sajjon

6

swift3.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];

}

그런 다음 ivar를 반환 값으로 설정하고 다음과 같이 유지할 수 있습니다.

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

14
이것은 질문에 대한 대답이 아닙니다.
— bluefloyd8 2013 년

1
라벨에 numberOfLines 또는 tag와 같은 다른 맞춤 매개 변수가 있으면 어떻게 되나요? 모든 속성을 설정 하시겠습니까?
— iamirzhan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.