视图弹出后如何从 uinavigationcontroller 中删除分段控制器?

Posted

技术标签:

【中文标题】视图弹出后如何从 uinavigationcontroller 中删除分段控制器?【英文标题】:How to remove segmentedcontroller from uinavigationcontroller after view pops? 【发布时间】:2010-05-18 09:55:07 【问题描述】:

我正在我的 viewDidLoad 方法中构建一个分段控件,如下所示:

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];

但是当用户返回 uinavigationcontroller 层次结构时,分段控制器仍停留在导航栏上。我将如何摆脱它?还是我做错了什么?


编辑

按照 Alex 的建议,我对标签进行了属性化并尝试了:

  NSArray *tabItems = [NSArray arrayWithObjects:@"FAQs", @"Terms", nil];
  self.tabs = [[UISegmentedControl alloc] initWithItems:tabItems];

但我不确定分配属性是否是个好主意;

我正在使用

  [self.tabs removeFromSuperview];

在我看来将消失。够了吗?

【问题讨论】:

【参考方案1】:

在视图控制器中保留对分段控件的引用(即将tabs 定义为视图控制器头文件中的属性)。

覆盖视图控制器的-viewWillDisappear: 方法,并使用控件的-removeFromSuperview 方法从导航栏中删除分段控件。

编辑

你仍然会在-viewDidLoadalloc-init 你的分段控件tabs。您只需在视图控制器的标题中为tabs 设置一个保留属性,并将控件的release 语句移动到视图控制器的dealloc 方法。

阅读Objective-C tutorial 的“属性”部分,了解属性的介绍以及如何设置它们。

重写方法的方式如下:

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

-viewWillDisappear: 的情况下,当您的视图控制器即将消失时调用此方法,例如当它从导航堆栈中弹出时。这是放置管理视图控制器特定项目(如分段控件)清理的代码的好地方:

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

编辑 2

如果你的属性设置如下:

@property (nonatomic, retain) UISegmentedControl *tabs;

那么你将去retain 任何你设置self.tabs 等于的东西。

你的代码在这里:

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

会造成内存泄漏,因为您保留了这个对象:[[UISegmentedControl alloc] init] — 但您永远不会释放 [[UISegmentedControl alloc] init] 本身。这很糟糕。

改为在右侧使用autorelease,即:

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

tabs 属性保留其对已初始化分段控件的引用。该初始化的分段控制本身会在稍后的某个时间点正确释放。所以没有更多的内存泄漏。

【讨论】:

谢谢。如何在不分配/初始化的情况下设置分段控件?您能否给我 viewWillDisappear 方法所需的代码行。谢谢 感谢“编辑 2”。除了自动释放的东西,我什么都准备好了。【参考方案2】:

更好的是,将 UISegmentedControl 的所属 UIViewController 的 navigationItem.titleView 设置为 UISegmentedControl。

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

    self.navigationItem.titleView = mySegmentedControl; 

不需要手动删除 UISegmentedControl 或任何其他 UIView,当然,除非在释放拥有 UIViewController 时释放。另外,要成为“好记性的公民”,您可以在 -viewDidUnload 中将您的属性设置为 nil。

还可以自定义UIViewController的navgiationItem的左右barButtonItems。

【讨论】:

以上是关于视图弹出后如何从 uinavigationcontroller 中删除分段控制器?的主要内容,如果未能解决你的问题,请参考以下文章

[对smartMenu.js改进] 解决右键菜单栏在边缘弹出后,移出视图区域无法操作的问题

UINavigationController 推送和弹出后 UIScrollView 子跳转

ios开发之--两次模态弹出后,怎么返回最上层的页面

ios 键盘在弹出后无法点击

弹出后如何选择 UITableView 的 indexPath?

从 create react native 弹出后在 android studio 中运行 react native 项目的步骤