Czy można skopiować UIView?

Po prostu używając tego sposobu:

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

Spowoduje to, że symulator nie może 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 dzielą tę samą pamięć z view1.

Dlaczego nie można skopiować UIView? Jaki jest powód?

Author: Paulo Mattos, 2010-12-13

6 answers

Twoja aplikacja prawdopodobnie zawiesza się z czymś takim jak:

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

Powodem jest to, że UIView nie implementuje protokołu kopiowania i dlatego nie ma selektora copyWithZone w UIView.

 33
Author: Engin Kurutepe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-15 13:54:19

To może Ci się udać ... zarchiwizuj widok, a następnie usuń jego archiwizację. To powinno dać ci głęboką kopię widoku:

id copyOfView = 
[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:originalView]];
 156
Author: j2emanue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-23 13:45:35

Możesz utworzyć rozszerzenie UIView. W przykładzie swift snippet poniżej funkcja copyView zwraca obiekt AnyObject, dzięki czemu można skopiować dowolną podklasę UIView, ie UIImageView. Jeśli chcesz skopiować tylko UIViews, możesz zmienić typ zwracania 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()
 22
Author: Ivan Porkolab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 22:26:10

Dla swift3. 0. 1:

extension UIView{
 func copyView() -> AnyObject{
    return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! as AnyObject
 }
}
 5
Author: Sour LeangChhean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 07:11:56

UIView nie implementuje protokołu NSCoping, patrz deklaracja w UIView.h :

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

Jeśli więc chcemy mieć metodę podobną do copy, musimy zaimplementować protokół NSCoping w jakiejś kategorii.

 0
Author: HongchaoZhang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-21 01:46:06

Możesz zrobić metodę coś takiego:

-(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 następujący sposób:

myLabel = [[self copyLabelFrom:myOtherLabel] retain];
 -6
Author: ssj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-15 18:40:30