如果我在viewDidLoad中以编程方式添加控件,如何从其他方法访问它?

时间:2012-05-12 07:51:14

标签: objective-c ios cocoa-touch

在我的主视图控制器的viewDidLoad方法中,我以编程方式创建一个分段控件,然后将其添加到我的导航控件的titleView中。

NSArray *seggieItems = [[NSArray alloc] initWithObjects:@"See Entire List",@"See Near Me", nil];
UISegmentedControl *seggie = [[UISegmentedControl alloc]initWithItems:seggieItems];
[seggie setSegmentedControlStyle:UISegmentedControlStyleBar];
[seggie setTintColor:[UIColor redColor]];
[seggie addTarget:self
           action:@selector(seggieChanged:)
 forControlEvents:UIControlEventValueChanged];


self.navigationItem.titleView = seggie;

但是,当我想从另一种方法(例如viewWillAppear)访问此分段控件时,我无法 - 它是未声明的标识符。

    - (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [seggie setSelectedSegmentIndex:0]; //this should always be 0 for this view controller viewDidLoad method

}

如果我使用XIB,这将没有问题,因为我有一个可以从任何地方使用的IBOutlet。我尝试为我的Segmented控件创建一个属性,但实例变量隐藏了局部变量,所以这必须是错误的方法。

最好的方法是什么?如果这是一个愚蠢的问题我很抱歉 - 我对iOS很新,目前大约有几本书。我无法在Google上找到答案或搜索StackOverflow。我很感激任何帮助,如果这很简单我很遗憾,我很抱歉。感谢

5 个答案:

答案 0 :(得分:3)

将其作为财产是正确的方法。如果你这样做,并获得你描述的掩码警告,你可能仍然在viewDidLoad方法中声明seggie变量。删除该声明,并始终引用self.seggie而不是seggie,你会没事的。

声明我的意思是这一行:

UISegmentedControl *seggie = [[UISegmentedControl alloc]initWithItems:seggieItems];    

应该是

self.seggie = [[UISegmentedControl alloc]initWithItems:seggieItems];

答案 1 :(得分:3)

有两种方法可以做到这一点: -

1>在.h文件(全局)中声明UISegmentedControl的对象,除非您想从其他类访问,否则同一个类不需要属性。

2>您可以遍历父视图的子视图并获取UISegmentedControl并对其进行类型转换以执行操作,例如: -

NSArray *subviewss=[self.view subviews];
for(int i=0;i<[subviewss ;i++])
{
if([[subviews objectAtIndex:i] isKindOfClass:[UISegmentedControl class]])
{
UISegmentedControl *segmentControl= (UISegmentedControl *) [subviewss objectAtIndex:i];
[segmentControl setSelectedSegmentIndex:0];

}
}

但只有在viewcontroller中只有一个分段控件作为子视图时,上面的循环代码才会出现问题,否则它会碰到类型为UISegmentedControl的任何东西。

答案 2 :(得分:2)

将此UISegmentedControl *seggie;代码行放在.h(标题)文件中,或将其设为全局!

您不能在其他方法中使用本地创建的对象。 Local and Instant Variable。这是针对java的,但我希望你能理解主要的想法。

答案 3 :(得分:2)

以上建议选项很好,可以创建属性或类宽/全局变量。 如果您不想定义属性或类宽/全局变量,还有一种方法 -

访问控制,如 -

for (int index = 0; index < [self.view.subviews count]; index++) {
    if([[self.view.subviews objectAtIndex:index] isKindOfClass:[UISegmentedControl class]]) {
        UISegmentedControl *seggie = (UISegmentedControl *) [self.view.subviews objectAtIndex:index];
        [seggie setSelectedSegmentIndex:0];
    }
}

不是评论,而是一些一般性建议

是的,这确实是获取视图效率最低的方式。

首先,如果你使用快速枚举,你至少可以摆脱重复使用

[self.view.subviews objectAtIndex:index]

来电,这真的是

[[[self view] subviews] objectAtIndex:index]

方法调度很快,但这并不意味着你不应该考虑你的代码实际在做什么。

您的代码不考虑多个控件,因为它们都被视为相同(例如设置为0)。

一旦找到你想要的对象,也不会提前退出此循环。如果你坚持骑自行车通过观点至少做得很好 -

for (UISegmentedControl *seggie in [self.views.subviews]) { 
    if ([seggie isKindOfClass:[UISegmentedControl class]]) { 
        seggie.selectedSegmentIndex = 0; 
        break; 
    } 
}

答案 4 :(得分:1)

你必须要成为

的财产
UISegmentedControll *seggie

在头文件中,或使数组全局。

如果您没有选择,我会尝试使用

访问它
UISegmentedControl * temp = self.navigationController.titleView;
[temp setSelectedSegmentIndex:0];