Можно ли скопировать UIView?

Просто используя этот способ

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

Это приведет к тому, что симулятор не сможет запустить это приложение.

Попробуйте сохранить,

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

Любые изменения в view2 будут применяться к view1, я понимаю, что view2 использует одну и ту же память с view1.

Почему нельзя копировать UIView? В чем причина?

Ответ 1

Ваше приложение, вероятно, сработает с чем-то вроде:

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

Причина в том, что UIView не реализует протокол копирования, и поэтому в UIView нет селектора copyWithZone.

Ответ 2

это может сработать для вас... архивируйте представление, а затем сразу же отпустите его. Это должно дать вам глубокую копию представления:

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

Ответ 3

Вы можете сделать расширение UIView. В приведенном ниже примере быстрого фрагмента функция copyView возвращает AnyObject, чтобы вы могли скопировать любой подкласс UIView, то есть UIImageView. Если вы хотите скопировать только UIViews, вы можете изменить тип возврата на 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()

Ответ 4

для swift3.0.1:

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

Ответ 5

UIView не реализует протокол NSCoping, см. объявление в 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];