プロが教えるわが家の防犯対策術!

突然の質問失礼致しますm(_ _)m

ナビゲーションバーを使用したアプリを作っています。
右に「使い方」の画面へ遷移するUIBarButtonItemを配置したいと考えております。

このとき、各画面のボタンの配置、遷移したときのアクションを書けば
遷移できるのは確認できたのですが、全てのページにそれを書くのがあまり
よくないような気がしています。

ボタンとボタンのアクションを共通化することは可能でしょうか?
また、その場合どのファイルにどのように書くのが後々の変更等にも耐えやすいでしょうか?
(例えば、「使い方」ボタンを「設定」ボタンに変更する等。。。)


実装しているボタンとボタンのアクションのソースは以下になります。

//ボタンの配置(viewDidLoad)

UIBarButtonItem *btn = [[UIBarButtonItem alloc]
initWithTitle:@"使い方"
style:UIBarButtonItemStylePlain
target:self
action:@selector(howtoButtonTouched:)];

self.navigationItem.rightBarButtonItem = btn;


//ボタンのをタップしたときのアクション

-(void)howtoButtonTouched:(id)sender {
//使い方画面へ遷移
HowtoViewController *howtoViewController = [[HowtoViewController alloc] init];
[self.navigationController pushViewController:howtoViewController animated:YES];
}


どなたか、良い方法があればご教授頂けますと
大変ありがたいです。

「【iphoneアプリ開発】ボタン&処理の」の質問画像

A 回答 (3件)

クラスの継承を利用すれば可能でしょう。

というより、ここでクラスの継承を使わなくて、なんのためのオブジェクト指向?という話ですね。

共通の親ViewController(仮にParentViewController)を作り、画面A、B、C、DのViewControllerをこのParentViewControllerの子クラスにします。
全画面で共通するオブジェクト(この場合はBarButtonItem)は、ParentViewControllerに実装し、個別のオブジェクトは各ViewControllerに実装する。
これでかなりの手数を省略できるでしょう。
    • good
    • 0
この回答へのお礼

お忙しい中ありがとうございます!!

なるほど!!
継承すればよいのですね!

アドバイス頂きましたように、
CommonViewControllerという親ViewControllerを作って、
そこに、ボタンとボタンアクションを配置。
各画面では、CommonViewControllerを継承して
やりたい事が実現出来ました!!

ありがとうございますっ!!!

お礼日時:2014/06/12 21:20

No.1です。



> 下記の様なコードを書いてみたのですが、
> ナビゲーションバーは表示されるのですが、
> ボタンは表示されなようでした。。。

そのコードは、
naviController.navigationItem.rightBarButtonItem = btn;
が誤っていますのでボタンは表示されません。
rightBarButtonItemは、NavigationControllerのnavigationItemではなく
各ViewControllerのnavigationItemに設定しないと
ボタンは表示されません。

つまり、rightBarButtonItemは各VCに設定するものなので、
そのVCをロードしたタイミングでないと設定できません。

元々私が言いたかったのは、didFinishLaunchingWithOptionsの
タイミングでボタンを設定するのではなく、
例えばAppDelegateクラスに
- (void)createHowToButton:(UIViewController *)vc;
というメソッドを新規作成し、その中でボタン生成処理を行い、

各VCのviewDidLoadのタイミングで
AppDelegate *app = [UIApplication sharedApplication].delegate;
[app createHowToButton:self];
といった形で、そのcreateHowToButtonメソッドを呼べばよいと言うことです。

その画面説明がTOP画面でも表示すべきものなら、TOP画面のクラスに
createHowToButtonメソッドとアクション処理メソッドを書き、
各VCからcreateHowToButtonを呼び出すようにしてもよいと思います。

ただ、子供が親を参照すると、通常循環参照に陥りますから、
親オブジェクトはdelegateのようにweak属性で参照するといった注意は必要です。
    • good
    • 0
この回答へのお礼

お忙しい中、丁寧に教えて頂きありがとうございます!

勘違いしておりました。
スミマセン。

AppDelegateをりようすると、おっしゃるように参照がややこしくなるとの、
継承すれば、ボタンと、アクションを一つのファイルに記述する事も出来て、
可読性もよいかとおもいましたので、今回はそちらで実装しようと思います。

お忙しい中、色々とご教授頂きまして、
本当に本当にありがとうございました。

お礼日時:2014/06/12 21:28

実際にやってみたことはないですが、


「target:self」をselfじゃなくて、どこか共通の
クラスのインスタンスにして、「action:」で
そのクラスに定義した共通メソッドを呼べば
アクションの共通化はできると思います。

共通のクラスは、簡単にやるならAppDelegateのインスタンス
とか使えると思います。
ボタンを生成する処理もAppDelegateのメソッドで定義して
共通化できると思います。

ただ、そこまで共通化すべきか疑問です。

そもそも「使い方画面」は既に別クラスで定義されていて、
説明表示自体はそのクラスの中で共通化されています。
現状、各画面のメソッドからそれを呼び出しているだけです。

今回は、そのボタン生成や呼び出し処理まで共通化しようとしている
のだと思いますが、そもそもA、B、C、D画面それぞれの
使い方って、それぞれ異なる説明にすべきという話は
ありませんか?(逆にほととんど同じ説明でよいのであれば
A、B、C、D画面のクラスから共通化すべきではありませんか?)

将来の変更に耐えやすいのは、共通化してしまうことでなく、
一部の画面に特別な説明を加えたくなった時に、
別の画面に影響を与えないで改造できる構造にする
という考えもあると思います。
(だからA、B、C、Dクラスを分けて定義したのではないですか?)

もし画面の使い方を説明しているのではなく、アプリ全体の使い方を
説明しているのであれば、TOP画面に使い方の説明画面をつけるべき
ではないかという話もあります。
そうした上で各画面からもその全体説明をリンクしたいのであれば、
そのTOP画面に共通メソッドを作り、それを呼び出すようにしても
よいと思います。
    • good
    • 0
この回答へのお礼

お忙しい中ご回答頂ありがとうございます!!

>共通のクラスは、簡単にやるならAppDelegateのインスタンスとか使えると思います。
>ボタンを生成する処理もAppDelegateのメソッドで定義して共通化できると思います。

下記の様なコードを書いてみたのですが、
ナビゲーションバーは表示されるのですが、
ボタンは表示されなようでした。。。
(すみません。あんましわかってないので見当違いのことをしているかもです。。。)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{


naviController = [[UINavigationController alloc] initWithRootViewController: self.topViewController];

UIBarButtonItem *btn = [[UIBarButtonItem alloc]
initWithTitle:@"使い方"
style:UIBarButtonItemStylePlain
target:self
action:@selector(howtoButtonTouched:)];

naviController.navigationItem.rightBarButtonItem = btn;

[self.window addSubview:naviController.view];
[self.window makeKeyAndVisible];

return YES;
}


>別の画面に影響を与えないで改造できる構造にするという考えもあると思います。
>(だからA、B、C、Dクラスを分けて定義したのではないですか?)

確かに、おっしゃる通りだと思います。
ただ、今回添付画像は説明用に色々省略していたのですが、
実は画面は4画面だけではなくもう少したくさんあります。
(A画面には、Aー1→Aー2→Aー3... と続くページがあったりします)
view自体も、ウェブビューだったり、テーブルビューだったり、バラバラなので、
ナヴィゲーションの部分は同じなので共通にしたいと思った次第です。



>「target:self」をselfじゃなくて、どこか共通のクラスのインスタンスにして、「action:」でそのクラスに定義した共通メソッドを呼べばアクションの共通化はできると思います。

クラスに定義した共通メソッドという所がちょっとわからないのですが、
画面遷移等、設計を変えることは難しそうなので、その方向で少し調べてみます。
(何かヒントがあったら教えてもらえるとすごくありがたいです。)

ありがとうございました。

お礼日時:2014/06/12 11:32

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!