Create elements programmatically and reuse code

I need to create several buttons and labels programmatically. For the most part, they will have the same attributes (opaque, backgroundColor, textColor) with the exception of the text, tag, and frame.

While trying to limit the amount of code I needed to type, I figured this would work:

// generate generic properties for our buttons
UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
tempButton.opaque = true;
tempButton.backgroundColor = [UIColor whiteColor];
tempButton.titleLabel.font = [UIFont fontWithName:@"Helvitica-Bold" size:15];;
[tempButton setTitleColor:[UIColor magentaColor] forState:UIControlStateNormal];
[tempButton addTarget:self action:@selector(handleButtonTap:) forControlEvents:UIControlEventTouchUpInside];

// generate specific button1 properties, assign to ivar, and display
tempButton.frame = CGRectMake(81, 136, 159, 37);
tempButton.tag = BUTTON_1_TAG;
[tempButton setTitle:@"button 1 title" forState:UIControlStateNormal];
self.button1 = tempButton;
[self.view addSubview:self.button1];

// generate specific button2 properties, assign to ivar, and display
tempButton.frame = CGRectMake(81, 254, 159, 37);
tempButton.tag = BUTTON_2_TAG;
[tempButton setTitle:@"button 2 title" forState:UIControlStateNormal];
self.button2 = tempButton;
[self.view addSubview:self.button2];

As most of you already know, only the last button is displaying. I assume this is because all I'm really doing is overwriting tempButton.

Is there a solution that allows me to accomplish what I'm trying to do here, without having to create separate "temp" variables for each element?

Also, it seems like there would be memory leak problems with my code above. My understanding is that tempButton is originally autoreleased, but every time I use it to set my ivar's, isn't it getting retained again? After doing that, would I need to send tempVar a release so it goes back down to 1, so that when autorelease is triggered, it will actually be deallocated?

Thanks for your help!


1.) You are assigning a new UIButton to a temporary variable. It is just an assignment. The assignment doesn't retain, so you have no memory leak.

2.) You can make a method that returns a partially configured button, then just set the different parts:

- (UIButton *)myButton {
  UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  tempButton.opaque = true;
  tempButton.backgroundColor = [UIColor whiteColor];
  tempButton.titleLabel.font = [UIFont fontWithName:@"Helvitica-Bold" size:15];;
  [tempButton setTitleColor:[UIColor magentaColor] forState:UIControlStateNormal];
  return tempButton;
}


....
IButton *tempButton = [self myButton];
[tempButton setTitle:@"button 1 title" forState:UIControlStateNormal];
tempButton.frame = CGRectMake(81, 136, 159, 37);
[self.view addSubview:tempButton];
tempButton = [self myButton];
tempButton.frame = CGRectMake(81, 254, 159, 37);
[tempButton setTitle:@"button 2 title" forState:UIControlStateNormal];
[self.view addSubview:tempButton];

Since you've given your buttons unique tags, you don't need to assign to iVArs like self.button1, self.button2, you can just use [self.view viewForTag: ] to retrieve the correct subview.

But, as the other guy says, if you do use 'self.button1 = ', the button is retained, and you'll need to release in your dealloc, and worry about calls to -[view didUnload] -- if you don't release there, then you'll have pointers to buttons that are no longer in the view.


You could create a method that builds your "tempButton".

- (UIButton *)createTempButton {
    UIButton *tempButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    tempButton.opaque = true;
    tempButton.backgroundColor = [UIColor whiteColor];
    tempButton.titleLabel.font = [UIFont fontWithName:@"Helvitica-Bold" size:15];;
    [tempButton setTitleColor:[UIColor magentaColor] forState:UIControlStateNormal];
    [tempButton addTarget:self action:@selector(handleButtonTap:) forControlEvents:UIControlEventTouchUpInside];
    return tempButton;
}

Then you can just call that when you need a new "tempButton".

UIButton *aTempButton = [self createTempButton];

  • You have to create separate button objects. As UIButton does not conform to NSCopying protocol, there's no easier way of doing it. If you are making many, write a method that creates a button, set common properties and returns the object. Another way is to make a Nib file and make instances.

  • Does self.button = ... retain your button? Yes if the setter for the property retains it. You will have to release it when the view id unloaded or deallocated.

  • 链接地址: http://www.djcxy.com/p/74236.html

    上一篇: 如何设置只有顶部的cornerRadius

    下一篇: 以编程方式创建元素并重用代码