web-dev-qa-db-ja.com

UINavigationControllerのカスタム戻るボタン

開発中のアプリケーションでは、ナビゲーションバーにカスタムの戻るボタンを表示する必要があります。ボタンアセットをPNG画像として、次のコードを書いています。

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    backButton.frame = CGRectMake(0, 0, 79, 29.0);
    [backButton setImage:[UIImage imageNamed:@"button_back.png"] forState:UIControlStateNormal];
    self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:backButton] autorelease];

}

このViewControllerを押すと、カスタムボタンが表示されず、代わりに、このViewControllerのタイトルが入った標準の戻るボタンが表示されます。

私がすでに試したこと:

  1. ボタンbackButtonがビュー階層に追加して、正しく作成されていることを再確認します。正しく表示されます。
  2. 同じ方法で、titlenavigationItemプロパティを変更し、それが(予想どおり)[戻る]ボタンのコンテンツを変更することを確認しました。

誰かが私が間違っていることを発見できますか? UINavigationControllerで戻るボタンとしてカスタム画像を使用することに成功した人はいますか?

18
pgb

backBarButtonItemプロパティは意図したとおりに機能しますが、ナビゲーションバーの色合いの色に基づいて、常に標準のボタンの形状と色が追加されます。

テキストをカスタマイズすることはできますが、画像を置き換えることはできません。

Andrew Pouliotが提案した回避策の1つは、代わりにleftBarButtonItemを使用することですが、代わりに標準のボタンを使用しました。

5
pgb

IOS 5以降、これは簡単です。

[[UIBarButtonItem appearance]
            setBackButtonBackgroundImage:[UIImage imageNamed:@"back_button.png"]
            forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

これをアプリデリゲートに配置すると、背景画像がアプリのすべての戻るボタンに設定されます(もちろん、そのコントロールの状態とバーの指標について)。

18
Matías R

https://stackoverflow.com/a/16831482/1719 から私のソリューションを再投稿しています:

UIViewControllerに簡単なカテゴリを作成します。

UIViewController + ImageBackButton.h

#import <UIKit/UIKit.h>

@interface UIViewController (ImageBackButton)

- (void)setUpImageBackButton;

@end

UIViewController + ImageBackButton.m

#import "UIViewController+ImageBackButton.h"

@implementation UIViewController (ImageBackButton)

- (void)setUpImageBackButton
{
    UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 34, 26)];
    [backButton setBackgroundImage:[UIImage imageNamed:@"back_arrow.png"] forState:UIControlStateNormal];
    UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.leftBarButtonItem = barBackButtonItem;
    self.navigationItem.hidesBackButton = YES;
}

- (void)popCurrentViewController
{
    [self.navigationController popViewControllerAnimated:YES];
}

@end

これで、すべてのビューコントローラー、または他のビューコントローラーが継承して#import UIViewController+ImageBackButton.hメソッドを実装するカスタムベースビューコントローラークラスでviewWillAppear:を実行するだけです。

- (void)viewWillAppear:(BOOL)animated
{
    [self setUpImageBackButton];
}

それで全部です。これで、どこにでも画像の戻るボタンがあります。国境なし。楽しい!

13

ストーリーボードから好きな画像や色でデザインし、新しいアクションをコントローラーにドラッグするだけの簡単なソリューションではありませんか?

スウィフトコード

@IBAction func backButton(sender: AnyObject) {
    self.navigationController?.popViewControllerAnimated(true)
}
4
vladCovaliov

紛らわしいことにbackBarButtonItemは探しているものではありません。

次のビューコントローラの戻るボタンのタイトルを制御するだけです。必要なのは、leftBarButtonItemをカスタムの戻るボタンに設定することです。

3
Andrew Pouliot

Johannes Fahrenkrugの回答は機能しますが、背面の画像は非常に配線された位置に表示されます。

ここで、画像を適切な場所に配置するためのより良い方法を見つけました。

サイズが24x24(@ 1x)の背面画像があることを確認します。これをbackImageと呼びます

アプリの起動時に次のコードを実行します

UINavigationBar.appearance().barTintColor = nil
UINavigationBar.appearance().backIndicatorImage = backImage
UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics: .Default)
2
duan

ここでこの回答を参照してください: INavigationControllerのカスタムビューでbackBarButtomItemを作成する方法

必要なのは、navigationControllerのbackBarButtonItemプロパティを設定するだけですbefore viewControllerをプッシュします。たとえば、viewControllerのbackBarButtonItemメソッドでviewDidLoadプロパティを設定しても機能しません。

1
SundayMonday

OOPによると、ViewController自体がその戻るボタンについて何も知っているべきではないと思います。これは、UINavigationControllerなど、ビューコントローラーが挿入されるcontainerViewControllerの責任です。

NavigationControllerをサブクラス化し、次のようにsuperClassメソッドでオーバーロードします。

@implementation STONavigationController

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [super pushViewController:viewController animated:animated];
    if ([self.viewControllers indexOfObject:viewController] != NSNotFound &&
        [self.viewControllers indexOfObject:viewController] > 0){
        UIImage *img = [UIImage imageNamed:@"back-1"];
        UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, img.size.width * 2, img.size.height * 2)];
        [backButton setBackgroundImage:img forState:UIControlStateNormal];
        UIBarButtonItem *barBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        [backButton addTarget:self action:@selector(popCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
        viewController.navigationItem.leftBarButtonItem = barBackButtonItem;
        viewController.navigationItem.hidesBackButton   = YES;
    }
}

- (void)popCurrentViewController
{
    [self popViewControllerAnimated:YES];
}

@end 
1

UIBarButtonItemに埋め込まれたUIButtonの代わりにUIBarButtonItemを作成するだけです。正常に動作します!

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"button_back.png"] style:UIBarButtonItemStyleBordered target:nil action:nil];

self.navigationItem.backBarButtonItem = backButton; 
0
romrom