Можно ли скопировать UIView?
просто используя этот путь:
UIView* view2 = [view1 copy]; // view1 existed
это вызовет симулятор не может запустить это приложение.
попробуйте сохранить
UIView* view2 = [view1 retain]; // view1 existed
// modify view2 frame etc
любые модификации для view2
будут применены к view1
, Я понимаю, что view2
поделиться той же памяти с view1
.
почему UIView
скопировать? В чем же причина?
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];