2009-08-14 6 views
2

私のビュー用に手動でUINavigationBarを管理しています。 Bar自体と最初のUINavigationItemは、Interface Builderで作成されます。私のコードでは、さまざまなイベントに基づいて、新しいナビゲーションアイテムをバーにプッシュし、適切なビューをメインビューのサブビューとしてペイントします。それはすべて問題ないと思われますが、Navbarの戻るボタンを選択すると、2つのアイテムが1つのアイテムスタックから切り取られ、予想通りに1つのアイテムスタックから外されます。テストするために、私はバーとトラップ2つのデリゲートメソッドのためのデリゲートとしての私のコントローラを設定します。UINavigationBarは「戻る」でスタックから2つのアイテムをポップしているようです

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

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

私は、右のポップの前に、ナビゲーションバー内の項目が正しいことを発見しましたポップしたアイテムが最後のアイテムであっても、ポップ直後の2番目のメソッドではアイテムが1になります。何とか中間アイテムが欠落しています。私はこれをどのようにデバッグするのか困惑しており、どんな考えにも感謝しています。

私はさまざまな理由でナビゲーションコントローラを使用していないことに注意してください。

答えて

0

"私のビューでは UINavigationBarを手動で管理しています。"

しないでください。 ;-)

真剣に。私はあなた自身でそれを管理する正当な理由を考えることはできません。あなたが非常に慎重ではない場合、あなたはアプリケーション全体を扱いにくくする問題にぶつかるでしょう。では、XIBに接続されているルートビューにUINavigationControllerを作成するだけではいかがですか?あなた自身でnavバーを管理することによって克服しようとしている問題は何ですか?

あなたが抱えている問題については、shouldPopItemで何かをしているために2つのポップが表示されます。これは再びポップするように指示しています。これはnavバーを自分で管理しようとする効果です。 shouldPopItemとdidPopItemはナビゲーションバーとナビゲーションコントローラおよびビューには関連しないことに注意してください。あなたが[[self navigationController] popViewControllerAnimated:YES]でビューコントローラをポップすると、 shouldPopItemが呼び出されます。あなたはそれを上書きしているので、すべてを管理する必要があります。

+0

のようにユーザーが開始またはプログラムである場合は、[はい、ありがとう。おそらく何かがdidPopItemとshouldPopItemを2回呼び出すと思っていたので、私はそれらをトラップできるようにデリゲートメソッドを設定しました。彼らは一度だけ呼び出されます。 ナビゲーションコントローラを実装するよりもviewcontrollerを拡張する方が簡単だったようです。そして、IBがこれを設定するツールをあなたに与えたら、それはOKだろうと思った。加えて、私はかなりiphone devには新しく、フレームワークの仕組みを理解するのが好きです。私は今、自分のやり方で仕事をしてきました。そして、これを私の理解を逃れた環境で、もう一つ別のものに挑戦しました... – farhadf

0

shouldPopItemdidPopItemの方法の冒頭にNSLog()というステートメントを挿入することから始めます。これにより、何回呼び出されているかを知ることができます。次に、View Controllerスタックのサイズをアプリ全体のさまざまな場所に記録することができます。どちらも動作しない場合は、ブレークポイントの設定とスタックトレースのチェックを開始するか、コントローラのスタックサイズを手動で表示してください。

+0

ありがとう - 私は私のポストではきれいではありませんでした - ブレークポイントを設定し、スタックのサイズとスタックの内容を表示します。非常に奇妙な。 – farhadf

0

UINavigationControllerのようなコアクラスを置き換えたり除外したりすることは、決して受け入れられません。私を信じて、私は広範囲にこれをやった人を見ました。そして、アプリは問題に満ちていました - そして、私はそれらに対処しなければなりませんでした。 UINavigationController.hをご覧ください。なぜなら、あなたは自分のナビゲーションバーを管理しようとしているのですか?

代わりに、UINavigationBarのようなクラスを「軽く」サブクラス化して、特定の描画/レイアウトメソッドをオーバーライドすることは許容されます。そうすることで、すべての複雑なロジックを意図したベースクラスに戻すことができます。あなたはすべてのためにこれを行うことができます

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

:あなたがする探しているすべては、たとえば、それをカスタムイメージスタイルであれば

はさらに良いことに、ちょうどナビゲーションバーのcontents性質を利用しますUIViewサブクラスを使用すると、画像を使用して見た目を簡単かつきれいに変更できます。もちろん、カスタム図面を作成する場合は、サブクラスUINavigationBarをサブクラス化し、-drawRect:メソッドのみをオーバーライドします。そのサブクラスをの代わりに標準UINavigationControllerで使用すると、カスタムスタイルのナビゲーションバーのみですべて正常に機能します。

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; 
} 
関連する問題