Po prostu używając w ten sposób:
UIView* view2 = [view1 copy]; // view1 existed
Spowoduje to, że symulator nie będzie mógł uruchomić tej aplikacji.
Spróbuj zachować,
UIView* view2 = [view1 retain]; // view1 existed
// modify view2 frame etc
Wszelkie modyfikacje view2
będą miały zastosowanie do view1
, rozumiem, że view2
mają tę samą pamięć z view1
.
Dlaczego nie można UIView
go skopiować? Jaki jest powód?
ios
objective-c
uiview
copy
Forrest
źródło
źródło
to może zadziałać ... zarchiwizuj widok, a następnie rozpakuj go. To powinno dać ci dokładną kopię widoku:
id copyOfView = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];
źródło
UIImageView
s :(Możesz zrobić rozszerzenie UIView. W poniższym przykładzie swift snippet funkcja copyView zwraca AnyObject, dzięki czemu można skopiować dowolną podklasę UIView, tj . UIImageView. Jeśli chcesz skopiować tylko UIViews, możesz zmienić typ zwrotu na UIView.
//MARK: - UIView Extensions extension UIView { func copyView<T: UIView>() -> T { return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self)) as! T } }
Przykładowe użycie:
let sourceView = UIView() let copiedView = sourceView.copyView()
źródło
dla swift3.0.1:
extension UIView{ func copyView() -> AnyObject{ return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! as AnyObject } }
źródło
UIView
nie implementujeNSCoping
protokołu, zobacz deklarację w UIView.h :@interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusEnvironment>
Tak więc, jeśli chcemy mieć
copy
podobną metodę, musimy zaimplementowaćNSCoping
protokół w jakiejś kategorii.źródło
Możesz zrobić taką metodę jak ta:
-(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]; }
Następnie możesz ustawić swój ivar na wartość zwracaną i zachować ją w ten sposób:
myLabel = [[self copyLabelFrom:myOtherLabel] retain];
źródło