2009-08-14 54 views
2

我手動管理我的視圖的UINavigationBar。 Bar本身和第一個UINavigationItem是在Interface Builder中創建的。在我的代碼中,基於各種事件,我將新的導航項目推送到欄上,並將適當的視圖作爲主視圖的子視圖進行繪製。這一切似乎都很好,但是當我選擇導航欄後退按鈕時,兩件物品會從物品堆棧中刪除,而不是像我所預期的那樣。爲了測試,我把我的控制器爲代表的酒吧和陷阱2委託方法:UINavigationBar似乎彈出2個項目在「後退」堆棧

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; 

- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item; 

我彈出前右發現,在導航欄的項目是正確的,例如,3.在第二種方法中,在彈出之後,即使彈出的項目是最後一個項目,項目也是1 - 不知何故中間項目丟失。我很難理解如何調試,並會欣賞任何想法。

請注意,由於各種原因,我沒有使用導航控制器。

回答

0

「我正在爲我的視圖手動管理一個 UINavigationBar。」

不這樣做。 ;-)

說真的。我想不出有一個很好的理由來管理它,如果你不是很小心,你會遇到的問題,使整個應用程序無法管理。那麼爲什麼不在你的根視圖中創建一個連接到你的XIB的UINavigationController呢?你想通過自己管理導航欄來克服什麼問題?

至於你遇到的問題 - 你得到兩個流行音樂,因爲你正在做的事情在shouldPopItem,告訴它再次彈出。這是試圖自己管理導航欄的效果。請記住,shouldPopItem和didPopItem只與導航欄相關,而不與導航控制器和視圖相關。當你用[[self navigationController] popViewControllerAnimated:YES]彈出視圖控制器;它會調用shouldPopItem。既然你壓倒一切,你必須管理一切。

+0

是的,謝謝。我在想,也許有人調用didPopItem和shouldPopItem兩次,這就是爲什麼我設置了委託方法,以便可以捕獲這些方法。他們只被調用一次。 當時看起來更容易擴展我的viewcontroller而不是實現導航控制器。考慮到IB給你提供的工具來設置它,我認爲它是可以的。另外,我對iphone開發相當陌生,並且喜歡理解框架機制。我已經在我的工作方式現在,並粉筆這與環境,以避免我的理解又一件事... – farhadf 2009-08-17 17:21:52

0

我會放置一個NSLog()聲明在您shouldPopItemdidPopItem方法從頭開始 - 這會給你的他們多少次獲取調用,當一個想法。接下來,您可以在應用程序中的各個位置記錄視圖控制器堆棧的大小,以便您可以觀察它的增長和縮小。如果這兩者都不起作用,只需手動開始放置斷點並檢查堆棧跟蹤/查看控制器堆棧大小即可。

+0

謝謝 - 我在我的帖子不是很乾淨 - 這正是我正在做的 - 設置斷點並查看堆棧的大小以及堆棧上的內容。很奇怪。 – farhadf 2009-08-17 17:20:16

0

幾乎從不可以接受替換或排除諸如UINavigationController之類的核心類。相信我,我看到有人廣泛地做到了這一點,而且這款應用充斥着各種問題 - 我不得不面對這些問題。只要看看UINavigationController.h。它正在管理大量的州,等等。你爲什麼試圖管理自己的導航欄?

取而代之的是,可以「輕輕地」將子類UINavigationBar這樣的子類重寫爲只覆蓋某些繪圖/佈局方法。這樣做可以讓所有複雜的邏輯按照預期回退到基類。

更妙的是,僅僅利用導航欄的contents財產如果所有你希望做的是風格的它,比如說,一個自定義圖像:

#import <QuartzCore/QuartzCore.h> 
... 
- (void)viewDidLoad 
{ 
    UIImage * navigationBarContents = [UIImage imageNamed:@"navigation-bar"]; 
    self.navigationController.navigationBar.layer.contents = 
     (id)navigationBarContents.CGImage; 
} 

你可以爲任何這樣做UIView子類可以輕鬆並乾淨地改變它們使用圖像的外觀。當然,如果你正在做自定義繪圖,只需要子類UINavigationBar並且只覆蓋-drawRect:方法。然後使用該子類代替標準UINavigationControllerUINavigationBar,並且所有內容都將按照正常情況運行,只能使用自定義樣式的導航欄。

0

我不知道爲什麼UINavigationBar的行爲像這樣,但我有一個棘手的解決方案。

- (BOOL)navigationBar:(UINavigationBar *)navigationBar 
    shouldPopItem:(UINavigationItem *)item 
{ 
    NSMutableArray *items = navigationBar.items.mutableCopy; 
    [items removeObject:item]; 

    // Now var 'items' contains the proper instances of UINavigationItem. To be exact, one more than the instances in 'navigationBar.items'. 

    return YES; 
} 
0

檢查,如果poppage是用戶發起或編程像這樣

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item 
{ 
    UIViewController *topViewController = self.topViewController; 

    ... some logic that justifies implementing shouldPopItem: delegate in the first place -> others have explained the caveats so I won't repeat that ... 

    // manual as in opposite of programmatic 
    BOOL manualPop = topViewController.navigationItem == item; 
    if(manualPop) { 
     [self popViewControllerAnimated:YES]; 
    } 
    return YES; 
}