简体   繁体   English

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

[英]If I add a control programmatically in viewDidLoad, how do I access it from other methods?

In my viewDidLoad method of my main View Controller I programatically create a segmented control and then add it to the titleView of my Navigation Control. 在我的主View Controller的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;

However when I want to access this Segmented Control from another method, such as viewWillAppear, I can't - it's an undeclared identifier. 但是,当我想从其他方法(例如viewWillAppear)访问此分段控件时,我不能-它是未声明的标识符。

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

}

If I was using a XIB this would be no problem since I'd have an IBOutlet I could use from anywhere. 如果我使用的是XIB,那将没有问题,因为我有一个IBOutlet,可以在任何地方使用。 I tried creating a property for my Segmented control, but then the instance variable hides the local variable, so this must be the wrong approach. 我尝试为我的Segmented控件创建一个属性,但是实例变量隐藏了局部变量,因此这一定是错误的方法。

What's the best way to go about this? 最好的方法是什么? I apologize if this is a stupid question - I'm fairly new to iOS, currently about halfway through a couple of books. 如果这是一个愚蠢的问题,我深表歉意-我对iOS还是相当陌生,目前大约在阅读几本书。 I couldn't find an answer on Google or searching StackOverflow. 我在Google或搜索StackOverflow上找不到答案。 I would appreciate any help, and I'm sorry if this is something really simple that I'm missing. 我将不胜感激,如果能提供的帮助确实很简单,我很抱歉。 Thanks 谢谢

Making it a property is the correct approach. 使其成为属性是正确的方法。 If you do that, and get the mask warnings you describe, you are probably still declaring the seggie variable in your viewDidLoad method. 如果这样做,并得到描述的掩码警告,则可能仍在viewDidLoad方法中声明seggie变量。 Remove that declaration and always refer to self.seggie instead of seggie and you'll be fine. 删除该声明,并始终引用self.seggie而不是seggie ,就可以了。

By declaration I mean this line: 通过声明,我的意思是这一行:

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

It should be 它应该是

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

There are 2 ways you can do this:- 有两种方法可以做到这一点:

1>Either declare the object for UISegmentedControl in the .h file (global) adn no property is needed for same class unless you want to access from some other class. 1>在.h文件(全局)中为UISegmentedControl声明对象,并且同一类都不需要属性,除非您希望从其他类进行访问。

2>You can iterate through subviews of the parentview and get the UISegmentedControl and typecast it to perfrom OPerations , such as:- 2>您可以遍历父视图的子视图并获取UISegmentedControl并将其类型转换为perfrom OPerations,例如:

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

}
}

but the above looped code will wrk only if you have only one segmented control as subview in your viewcontroller else it will bump into anything that is of class type UISegmentedControl. 但是上面的循环代码只有在您的viewcontroller中只有一个分段控件作为子视图时才会起作用,否则它将陷入UISegmentedControl类类型的任何事物中。

Put this UISegmentedControl *seggie; 把这个UISegmentedControl *seggie; line of code in your .h(header) file, or make it Global ! .h(header)文件中的代码行,或将其设置为Global!

You can't use a local created object in other method. 您不能以其他方法使用本地创建的对象。 Local and Instant Variable .It's for java but i hope you will understand the main idea. 局部变量和即时变量。它适用于Java,但我希望您能理解主要思想。

Above suggestion options are good, either create a property or class wide/global variable. 上面的建议选项是好的,可以创建属性,也可以创建类范围/全局变量。 One more approach, if you don't want to define property or class wide/global variable- 还有一种方法,如果您不想定义属性或类范围/全局变量,

access control like - 访问控制,例如-

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

Not really a comment but some general advice 并不是真正的评论,而是一些一般性建议

Yes this would indeed be the most inefficient way of getting a view. 是的,这确实是获取视图的最无效的方法。

For a start if you use fast enumeration you can at least get rid of the repeated use of the 首先,如果您使用快速枚举,则至少可以避免重复使用

[self.view.subviews objectAtIndex:index]

call, which is really 电话,这真的

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

method dispatch is fast but that doesn't mean you should not think about what your code is actually doing. 方法分配很快,但这并不意味着您不应该考虑代码实际在做什么。

Your code does not account for multiple controls as they are all treated the same (eg set to 0). 您的代码不考虑多个控件,因为它们都被视为相同(例如,设置为0)。

There is also no early exit from this loop once you have found the object you are after. 找到所要查找的对象后,也不会从此循环中提前退出。 If you insisted on cycling through the views at least do it nicely - 如果您坚持要在景观中循环浏览,至少要做得很好-

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

You gotta either make a property of 你要么做一个财产

UISegmentedControll *seggie

in your header file, or make the array global. 在头文件中,或将数组设为全局。

If that's no option for you, I would try accessing it using 如果那不是您的选择,我将尝试使用

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM