【问题标题】:How to remove segmentedcontroller from uinavigationcontroller after view pops?视图弹出后如何从 uinavigationcontroller 中删除分段控制器?
【发布时间】: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];

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

【问题讨论】:

    标签: iphone objective-c uinavigationcontroller uisegmentedcontrol


    【解决方案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。

    【讨论】:

      猜你喜欢
      • 2011-12-23
      • 2011-09-28
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多