I have IBOutlet UILabel *label;
and I want to do this
UILabel *label = [titleLabel copy];
label.text = @\"Clone\";
titleLabel.text = @
UILabel does not conform to NSCopying, so you cannot make a copy via -copy.
But it does conform to NSCoding, so you can archive the current instance, then unarchive a 'copy'.
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject: label];
UILabel *labelCopy = [NSKeyedUnarchiver unarchiveObjectWithData: archivedData];
Afterwards, you'll have to assign any additional properties that weren't carried over in the archive (e.g. the delegate) as necessary.
There is no public Apple API to deep copy a UILabel. Your best bet is to make a helper method which copies all the parts you care about.
- (UILabel *)deepLabelCopy:(UILabel *)label {
UILabel *duplicateLabel = [[UILabel alloc] initWithFrame:label.frame];
duplicateLabel.text = label.text;
duplicateLabel.textColor = label.textColor;
// etc... anything else which is important to your ULabel
return [duplicateLabel autorelease];
}
If you want to use it all over your code base you can change it to a static method and put it in some sort of utility class. If you named the class LabelUtils
you could do something like...
+ (UILabel *)deepLabelCopy(UILabel *)label {
// ...
}
and would be called using UILabel *dupLabel = [LabelUtils deepLabelCopy:origLabel];
I recommend using a merged version of Answer 1 and Answer 2:
- (UILabel *)copyLabel:(UILabel *)label {
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject: label];
UILabel* copy = [NSKeyedUnarchiver unarchiveObjectWithData: archivedData];
return copy;
}
Then simply use something like
UILabel* labelcopy = [self copyLabel:originalLabel];
in your code.
I created it as an extension to the UILabel
.
extension UILabel {
func createCopy() -> UILabel {
let archivedData = NSKeyedArchiver.archivedData(withRootObject: self)
return NSKeyedUnarchiver.unarchiveObject(with: archivedData) as! UILabel
}
}
let anotherNameLabel = nameLabel.createCopy()
NSKeyedArchiver
will take an object from memory and convert it to text. "Keyed" means it uses words to describe the properties of this object, like "LabelFrame", "LabelText", etc. (These are fake keys.) This also called Serialization in other technologies.
NSKeyedUnarchiver
does the opposite. It will take that text and build an object. Here we take that object (Any?
) and convert it to a UILabel
.
I solved it this way and wanted to post it for easy copy and pasting if you were thinking of doing the same.
func makeCopy() -> UILabel {
let label = UILabel(frame: frame)
label.text = text
label.font = font
label.textColor = textColor
label.shadowColor = shadowColor
label.shadowOffset = shadowOffset
label.textAlignment = textAlignment
label.lineBreakMode = lineBreakMode
label.attributedText = attributedText
label.highlightedTextColor = highlightedTextColor
label.isHighlighted = isHighlighted
label.isUserInteractionEnabled = isUserInteractionEnabled
label.isEnabled = isEnabled
label.numberOfLines = numberOfLines
label.adjustsFontSizeToFitWidth = adjustsFontSizeToFitWidth
label.baselineAdjustment = baselineAdjustment
label.minimumScaleFactor = minimumScaleFactor
label.allowsDefaultTighteningForTruncation = allowsDefaultTighteningForTruncation
label.preferredMaxLayoutWidth = preferredMaxLayoutWidth
return label
}