¿Se puede copiar UIView?


81

Simplemente usando de esta manera:

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

Esto hará que el simulador no pueda iniciar esta aplicación.

Intenta retener

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

Cualquier modificación view2se aplicará a view1, entiendo que view2comparten la misma memoria con view1.

¿Por qué no se UIViewpuede copiar? ¿Cuál es la razón?

Respuestas:


33

Tu aplicación probablemente se bloquee con algo como:

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

La razón es que UIView no implementa el protocolo de copia y, por lo tanto, no hay ningún copyWithZoneselector en UIView.


10
¿Qué debo hacer para implementar la copia de UIView?
Satyam

1
Entonces, si tiene una cierta combinación de UIView y desea usarla varias veces, necesitará subclasificar tal UIView.
Anonymous White

Sí, subclasificación o categoría con métodos de fábrica a nivel de clase que devuelven instancias preconfiguradas de esa vista.
Engin Kurutepe

162

esto podría funcionar para usted ... archive la vista y luego desarchive inmediatamente después. Esto debería darle una copia profunda de una vista:

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

1
Eso parece un truco pero funciona como un sueño. La respuesta de ssj a continuación es básicamente un 'constructor de copias' que está bien para clases pequeñas. Quizás pueda usar el tiempo de ejecución de obj-c para copiar todas las propiedades a la vez. Esto es aún más fácil;)
Patrick Borkowicz

1
Esto funciona, pero parece ser muy lento incluso para árboles de vista triviales.
Ian Newson

6
Funciona, ¡pero cuidado! No establece valores para @IBOutlets, todos ellos son nulos después de "copiar"
nalexn

1
Esto parece ignorar UIImageViews :(
Iulian Onofrei

1
¡Gracias, funciona muy bien! TAMBIÉN tenga en cuenta que la vista copiada no tiene supervista (padre), ni restricciones ni reconocedores de gestos (si el padre tenía alguno).
Sajjon

25

Puede crear una extensión UIView. En el siguiente fragmento de código rápido de ejemplo, la función copyView devuelve un objeto AnyObject para que pueda copiar cualquier subclase de un UIView, es decir , UIImageView. Si desea copiar solo UIViews, puede cambiar el tipo de retorno a UIView.

//MARK: - UIView Extensions

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

Uso de ejemplo:

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

1
¡Gracias, funciona muy bien! TAMBIÉN tenga en cuenta que la vista copiada no tiene supervista (padre), ni restricciones ni reconocedores de gestos (si el padre tenía alguno).
Sajjon

6

para swift3.0.1:

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

1

UIViewno implementa el NSCopingprotocolo, vea la declaración en UIView.h :

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

Entonces, si queremos tener un copymétodo similar, necesitamos implementar el NSCopingprotocolo en una categoría más o menos.


-6

Puedes hacer que el método sea algo como esto:

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

}

Luego puede establecer su ivar en el valor de retorno y retenerlo así:

myLabel = [[self copyLabelFrom:myOtherLabel] retain];

14
esto no responde a la pregunta.
bluefloyd8

1
¿Qué pasa si su etiqueta tiene otros parámetros personalizados como numberOfLines o tag? ¿Establecerás todas las propiedades?
iamirzhan
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.