n.evermind
n.evermind

Reputation: 12004

How to add the same subview to different views?

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?

Upvotes: 0

Views: 331

Answers (4)

csano
csano

Reputation: 13716

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.

Upvotes: 5

Michael Petrov
Michael Petrov

Reputation: 2317

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

Upvotes: 3

Daniel Dickison
Daniel Dickison

Reputation: 21882

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.

Upvotes: 1

arclight
arclight

Reputation: 5310

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

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

Upvotes: 1

Related Questions