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


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

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

это вызовет симулятор не может запустить это приложение.

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

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

любые модификации для view2 будут применены к view1, Я понимаю, что view2 поделиться той же памяти с view1.

почему UIView скопировать? В чем же причина?

6 78

6 ответов:

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

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

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

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

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

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

для swift3.0.1:

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

UIView не выполнять NSCoping протокол, см. объявление в UIView.h:

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

Итак, если мы хотим иметь copy как метод, нам нужно реализовать NSCoping протокол в категории или около того.

Вы можете сделать метод что-то вроде этого:

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