2012-05-12 29 views
1

在我的ViewDidLoad方法我的主要視圖控制器我編程方式創建一個分段控制,然後將其添加到我的導航控件的titleView。如果我在viewDidLoad中以編程方式添加控件,如何從其他方法訪問它?

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 

} 

如果我使用的是廈門國際銀行,這將是沒有問題的,因爲我有一個IBOutlet我可以從任何地方使用。我試着爲我的Segmented控件創建一個屬性,但是實例變量隱藏了局部變量,所以這必須是錯誤的方法。

這是什麼最好的方法呢?如果這是一個愚蠢的問題,我很抱歉 - 我對iOS相當陌生,目前大約有一兩本書的一半。我無法在Google上找到答案或搜索StackOverflow。我會很感激任何幫助,如果這件事很簡單,我很抱歉,我很抱歉。謝謝

+0

嘗試使用Google搜索範圍。這基本上是一個變量的生命週期。 – 11684

回答

3

使它成爲一個屬性是正確的方法。如果你這樣做,並得到你描述的面具警告,你可能仍然在你的viewDidLoad方法中聲明seggie變量。刪除該聲明,並始終參考self.seggie而不是seggie,你會沒事的。

通過聲明我的意思是這條線:

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

應該

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

完美解決了它,感謝您的幫助。我讓seggie成爲一個財產,然後改變了我的聲明,它的功能就像一個魅力。開始圍繞這些東西多一點,再次感謝。 – scotts7777

2

把這個UISegmentedControl *seggie;代碼行放在你的.h(頭文件)文件中,或者使它成爲Global!

您不能在其他方法中使用本地創建的對象。 Local and Instant Variable。這是爲java,但我希望你會明白的主要想法。

+0

謝謝,我明白我現在做錯了什麼。我將它從本地創建的分段控件切換到屬性,現在我可以從任何方法訪問它。感謝您的幫助 – scotts7777

1

你必須要麼使

UISegmentedControll *seggie 

屬性在你的頭文件,或使數組全局。

如果這對你沒有選擇,我會嘗試使用

UISegmentedControl * temp = self.navigationController.titleView; 
[temp setSelectedSegmentIndex:0]; 
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; 
    } 
} 
+0

不完全確定您的類變量是什麼意思,但在這種情況下全局變量不是最好的主意。一個財產或舊學校實例變量將是傳統的做法,對於新來的平臺來說,這並不是一個壞方法。 – Monolo

+0

@Monolo - 同意...最好的方法是使用屬性或實例變量? – rishi

+0

我認爲在這種情況下,屬性和實例變量之間的選擇是個人偏好的問題,特別是在ARC處理實例變量的內存管理時。就我個人而言,我會選擇一個在.m文件中聲明的實例var,以使其從公共接口中隱藏。但只要你不把它變成一個班級或全球變種,你就很好。 – Monolo

3

有2種方法可以做到這一點: -

1>無論是在聲明.h文件爲UISegmentedControl對象(全球)除非你想從其他類訪問,否則同一類不需要屬性。

2>您可以通過parentview的子視圖迭代,並得到了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]; 

} 
} 

但上面的循環代碼將WRK只有當你只有一個分割作爲子視圖控制在你的視圖控制器中,否則它會碰到任何類型爲UISegmentedControl的東西。

相關問題