开发者

How to remove segmentedcontroller from uinavigationcontroller after view pops?

I'm building a segmented control within my viewDidLoad method, like so:

NSArray *tabitems = [NSArray arrayWithObjects:@"ONE", @"TWO", nil];
UISegmentedControl *tabs = [[UISegmentedControl alloc] initWithItems:tabitems];
tabs.segmentedControlStyle = UISegmentedControlStyleBar;
tabs.frame = CGRectMake(185.0, 7.0, 130.0, 30.0);
tabs.selectedSegmentIndex = 0;
[self.navigationController.navigationBar addSubview:tabs];
[tabs release];

But when the user goes Back in the uinavigationcontroller hierarchy, the segmented controller stays on the navigation bar. How would I get rid of it? Or am I doing something fundamentally wrong?


EDIT

Following Alex's suggestions, I propertized tabs and tried:

  NSArray *tabItems = [NSArray arrayWithObjects:@"FAQs", @"Terms", nil];
  self.tabs = [[U开发者_高级运维ISegmentedControl alloc] initWithItems:tabItems];

but I'm not sure it's a good idea to alloc a property;

And I'm using

  [self.tabs removeFromSuperview];

in my viewWillDisappear. Is that enough?


Retain a reference to the segmented control in your view controller (i.e define tabs as a property in the view controller's header file).

Override the view controller's -viewWillDisappear: method, and remove the segmented control from the navigation bar there, using the control's -removeFromSuperview method.

EDIT

You would still alloc-init your segmented control tabs in -viewDidLoad. You just need to set up a retain property for tabs in your view controller's header, and move the control's release statement to the view controller's dealloc method.

Read the "Properties" section of this Objective-C tutorial for an introduction to properties and how to set them up.

The way to override a method is as follows:

- (ReturnClass) methodNameToOverride:args {
    [super methodNameToOverride:args];
    // your code goes here...
}

In the case of -viewWillDisappear:, this method gets called when your view controller is about to disappear, such as when it gets popped off the navigation stack. This is a great place to put code that manages clean-up of view-controller-specific items, like your segmented control:

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [tabs removeFromSuperview];
}

EDIT 2

If your property is set as follows:

@property (nonatomic, retain) UISegmentedControl *tabs;

then you are going to retain anything you set self.tabs equal to.

Your code here:

self.tabs = [[UISegmentedControl alloc] initWithItems:...];

will create a memory leak, because you are retaining this object: [[UISegmentedControl alloc] init] — but you never release [[UISegmentedControl alloc] init] itself. This is bad.

Instead, use autorelease on the right side, i.e.:

self.tabs = [[[UISegmentedControl alloc] initWithItems:...] autorelease];

The tabs property retains its own reference to the initialized segmented control. That initialized segmented control is itself released properly at some later point. So no more memory leak.


Even better, set the UISegmentedControl's owning UIViewController's navigationItem.titleView to the UISegmentedControl.

-(void) viewDidLoad {
    if(!mySegmentedControl) {
        // initialize the UISegmentedControl
        ...
    }

    self.navigationItem.titleView = mySegmentedControl; 
}

No manual removal of the UISegmentedControl or any other UIView for that matter required except, of course, releasing when owning UIViewController is dealloc'ed. Also, to be a "good memory citizen", you might set your property to nil in -viewDidUnload.

You can also customize the left and right barButtonItems of the UIViewController's navgiationItem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜