UIView를 복사 할 수 있습니까?


81

이 방법으로 간단히 사용 :

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

이로 인해 시뮬레이터가이 앱을 실행할 수 없습니다.

유지를 시도하십시오.

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

에 대한 모든 수정 사항 view2이에 적용될 것입니다 view1. 본인 view2view1.

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.