0

Sorry, a beginner's questions:

I have created an instance of an UILabel and would like to add copies of this UILabel to 4 different views. I tried the following code, but it won't work as I am assigning the UILabel to one view and then assign it to the next -- which results in the UILabel being removed from the first view. This carries on, so I end up with the UILabel being assigned only to the very last view:

 UILabel *titleTitle = [[[UILabel alloc] initWithFrame:CGRectMake(120, -48, 100, 28)] autorelease]; titleTitle.text = @"Index"; titleTitle.textColor = [UIColor blackColor]; titleTitle.backgroundColor = [UIColor clearColor]; titleTitle.font = [UIFont fontWithName:@"Ballpark" size:25.0f]; [indexView addSubview:titleTitle]; [indexView2 addSubview:titleTitle]; [indexView3 addSubview:titleTitle]; [indexView4 addSubview:titleTitle]; 

How can I manage to assign copies of UILabel to my views?

4 Answers 4

5

You can't do this. A view can only have one parent. If you want to define a label once and use a similarly defined label in multiple places, you should copy it.

EDIT: @Michael Petrov pointed out that UIView and its subclasses do not conform to the NSCopying protocol. My bad for overlooking this.

If the answer that he provided is too complicated for you, you can create a helper function that will generate a new instance of UILabel for you.

-(UILabel *) generateLabel:(CGRect) location { UILabel *label= [[[UILabel alloc] initWithFrame:location] autorelease]; label.text = @"Index"; label.textColor = [UIColor blackColor]; label.backgroundColor = [UIColor clearColor]; label.font = [UIFont fontWithName:@"Ballpark" size:25.0f]; return label; } 

And from your code:

UILabel *l1 = [self generateLabel:CGRectMake(...)]; [self addToSubView:l1]; [l1 release]; UILabel *l2 = [self generateLabel:CGRectMake(...)]; [self addToSubView:l2]; [l2 release]; 

.. and so on.

Sign up to request clarification or add additional context in comments.

3 Comments

UIView and its descendants typically don't support the NSCopying protocol. NSCoding is the correct way to do it).
@Michael Petrov: So how do I use NSCoding in this case? [titleTitle copy] won't work, right?
I upvoted your answer as it is the more correct and efficient way to do things, especially with something simple as labels. Archiving and unarchiving is a very heavy handed tactic that should be used only for copying large trees of nested UIViews (and then only after careful consideration).
3

This is probably overkill for your needs, but if you must copy a complex object, then archiving and unarchiving it should work:

NSMutableData *myData = [NSMutableData data]; NSKeyedArchiver *archiver = [[[NSKeyedArchiver alloc] initForWritingWithMutableData:myData] autorelease]; [archiver encodeObject:titleTitle forKey:@"myTitle"]; [archiver finishEncoding]; NSKeyedUnarchiver *unarchiver = [[[NSKeyedUnarchiver alloc] initForReadingWithData:myData] autorelease]; UILabel *t2 = [unarchiver decodeObjectForLey:@"myTitle"]; // set location attributes [view addSubView:t2]; [t2 release]; UILabel *t3 = [unarchiver decodeObjectForLey:@"myTitle"]; // set location attributes [view addSubView:t3]; [t3 release]; [unarchiver finishDecoding]; // Should be called once you will not decode any other objects 

Comments

1

That's impossible, a view can only have one parent.

You will need to remove it from the current parent to add it elsewhere.

Comments

1

A view can only be displayed in one parent view. So you'll need to create separate labels for each parent view. You can cut down on typing by writing a helper function.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.