视图弹出后如何从 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
方法从导航栏中删除分段控件。
编辑
你仍然会在-viewDidLoad
中alloc-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 子跳转
弹出后如何选择 UITableView 的 indexPath?
从 create react native 弹出后在 android studio 中运行 react native 项目的步骤