81 votes

UIView peut-il être copié ?

En utilisant simplement ce moyen :

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

Cela fera que le simulateur ne pourra pas lancer cette application.

Essayez de conserver,

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

Toute modification de view2 s'appliquera à view1 Je comprends que view2 partagent la même mémoire avec view1 .

Pourquoi ne peut-on pas UIView être copié ? Quelle en est la raison ?

162voto

j2emanue Points 3456

Ceci pourrait fonctionner pour vous ... archivez la vue et désarchivez-la juste après. Cela devrait vous donner une copie profonde d'une vue :

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

1 votes

La réponse de ssj ci-dessous est essentiellement un "constructeur de copie" qui est parfait pour les petites classes. Vous pouvez peut-être utiliser le runtime obj-c pour copier toutes les propriétés en une seule fois C'est quand même plus facile ;)

0 votes

Ça semble trop beau pour être vrai. Dans mon cas, une NSInvalidArgumentException est levée ( NSConcreteAttributedString initWithString:: nil value ) pour un UILabel dans l'arborescence de la vue secondaire.

1 votes

Cela fonctionne, mais semble être très lent pour les arbres de vue même triviaux.

33voto

Engin Kurutepe Points 3673

Votre application se plante probablement avec quelque chose comme :

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

La raison en est que UIView n'implémente pas le protocole de copie, et qu'il n'y a donc pas d'option de copie. copyWithZone sélecteur dans UIView.

10 votes

Que dois-je faire pour implémenter la copie de UIView ?

1 votes

Donc si vous avez une certaine combinaison d'UIView et que vous voulez l'utiliser plusieurs fois, vous devrez sous-classer cet UIView ?

0 votes

Oui, la sous-classification ou la catégorie avec des méthodes d'usine de niveau classe qui renvoient des instances préconfigurées de cette vue.

25voto

Ivan Porkolab Points 1829

Vous pouvez créer une extension UIView. Dans l'exemple ci-dessous, la fonction copyView renvoie un AnyObject, de sorte que vous pouvez copier n'importe quelle sous-classe d'un UIView, c'est-à-dire UIImageView. Si vous voulez copier uniquement UIViews, vous pouvez changer le type de retour en UIView.

//MARK: - UIView Extensions

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

Exemple d'utilisation :

let sourceView = UIView()
let copiedView = sourceView.copyView()

6voto

Sour LeangChhean Points 3212

Pour swift3.0.1 :

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

1voto

HongchaoZhang Points 944

UIView n'implémente pas le NSCoping voir la déclaration dans UIView.h :

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

Donc, si nous voulons avoir un copy nous devons mettre en œuvre la méthode NSCoping dans une catégorie ou une autre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X