Pregunta ¿Se puede copiar UIView?


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 a view2 se aplicará a view1, entiendo que view2 comparta la misma memoria con view1.

Por qué no puede UIView ser copiado? ¿Cual es la razon?


74
2017-12-13 05:04


origen


Respuestas:


Tu aplicación probablemente se cuelga con algo como:

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

El motivo es que UIView no implementa el protocolo de copiado y, por lo tanto, no existe copyWithZone selector en UIView.


32
2018-01-15 13:54



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

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

154
2017-12-07 02:33



Puede hacer una extensión UIView. En el siguiente fragmento rápido de ejemplo, la función copyView devuelve AnyObject para que pueda copiar cualquier subclase de un UIView, es decir UIImageView. Si quieres copiar solamente UIViews puede cambiar el tipo de devolución a UIView.

//MARK: - UIView Extensions

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

Ejemplo de uso:

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

21
2017-12-21 21:18



para swift3.0.1:

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

5
2018-03-20 07:11



UIView no implementa el NSCoping protocolo, vea la declaración en UIView.h:

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

Entonces, si queremos tener un copy como método, tenemos que implementar el NSCoping protocolo en una categoría más o menos.


0
2017-07-21 01:46



Puedes hacer un método como este:

-(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 configurar su ivar para el valor de retorno y retenerlo así:

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

-5
2018-04-15 18:40