まゆたまガジェット開発逆引き辞典

電子工作やプログラミングのHowtoを逆引き形式で掲載しています。作りたいモノを決めて学んでいくスタイル。プログラマではないので、コードの汚さはお許しを。参照していないものに関しては、コピペ改変まったく問いません

TabbarでNotificationを使ってデータ送信&-(void)を実行

TabbarでTab1のボタンを押すとTab2に書かれている-(void)〜が実行される。
オブジェクト指向で言う「委譲」ってやつですが、多くはDelegateを使うことが多いと思います。
が、ことStoryboardやTabbarなどを使っているとやりにくいことも。
そこで離れたViewにあるメソッドを実行する方法としてもうひとつ、Notificationがあります。
今回はNotificationを使って隣のTabにデータを送ったり、-(void)〜を実行してみました。
サンプルは以下になります。
GitHub - prince9/TabbarNotification: method of using Notification by Tabbar.TabbarでNotificationを使う方法です。違うタブにデータ送信&メソッド実行しています。

基本的に送信側(ボタンを押して-(void)〜を実行しろと指令を出す側)は

[[NSNotificationCenter defaultCenter] postNotificationName:@"P1" object:self];
となり、

受信側(-(void)〜が実行される側)は

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.   
    //通知を受信して-(void)receiveNotification1:を実行しろと命令する
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification1:) name:@"P1" object:nil];
}

//実際に実行されるコード、(NSNotification *) notificationを忘れずに
-(void)receiveNotification1:(NSNotification *) notification {
    count++;
    countText.text = [NSString stringWithFormat:@"%d",count];
}

になります。

詳しい解説は以下です。Tabbed Applicationで作成します。
FirstViewControllerにボタン2つ、スライダとTextFieldを設置します。
SecondViewControllerにラベルを4つ設置してそれぞれ結びつけます。

・FirstViewController.h

@interface FirstViewController : UIViewController
//スライダの値
@property (weak, nonatomic) IBOutlet UISlider *mySlider;
//テキスト
@property (weak, nonatomic) IBOutlet UITextField *myField;

//カウントボタン
- (IBAction)add:(id)sender;
//メッセージ表示ボタン
- (IBAction)textOn:(id)sender;
//キーボード隠す、テキスト入力の通知の作成と実行
- (IBAction)keyHide:(id)sender;
//スライドの値の通知の作成と実行
- (IBAction)sliderA:(id)sender;
@end

・FirstViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    //おまじない、Tab1つ目とTab2つ目を選択した状態にしておく。これがないと動かない・・・たぶんもっといい方法あります
    UITabBarController *controller = self.tabBarController;
    controller.selectedViewController = [controller.viewControllers objectAtIndex: 1];
    controller.selectedViewController = [controller.viewControllers objectAtIndex: 0];
    }
...
//カウンタの通知の作成と実行、2つ目のTabの-(void)receiveNotification1:を実行する
- (IBAction)add:(id)sender {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"P1" object:self];
    }

//メッセージの通知の作成と実行、2つ目のTabの-(void)receiveNotification2:を実行する
- (IBAction)textOn:(id)sender {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"P2" object:self];
}

//テキスト入力の通知の作成と実行、データを送るために使う
- (IBAction)keyHide:(id)sender {
    NSString *myF = myField.text;
    //送る値を作成
    NSDictionary *dic2 = [NSDictionary dictionaryWithObject:myF forKey:@"KEY2"];
    //通知を作成、実行
    [[NSNotificationCenter defaultCenter] postNotificationName:@"P4" object:self userInfo:dic2];
    //キーボード隠す
[myField resignFirstResponder];
}

//スライドの値の通知の作成と実行、データを送るために使う
- (IBAction)sliderA:(id)sender {
    //値を文字列に変換
    NSString *sv = [NSString stringWithFormat:@"%f",mySlider.value];
    //送る値を作成
    NSDictionary *dic1 = [NSDictionary dictionaryWithObject:sv forKey:@"KEY1"];
    //通知を作成、実行
    [[NSNotificationCenter defaultCenter] postNotificationName:@"P3" object:self userInfo:dic1];
   }
@end

・SecondViewController.h

@interface SecondViewController : UIViewController {
    //カウンタ用数値
    int count;
}
//カウンタの値表示
@property (weak, nonatomic) IBOutlet UILabel *countText;
//メッセージ表示
@property (weak, nonatomic) IBOutlet UILabel *mText;
//スライドの値表示 
@property (weak, nonatomic) IBOutlet UILabel *sliderValue;
//テキスト入力表示
@property (weak, nonatomic) IBOutlet UILabel *textF;
@end

・SecondViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    //カウンタ初期値
    count = 0;
    
    //通知を受信して-(void)receiveNotification1:を実行
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification1:) name:@"P1" object:nil];
    //通知を受信して-(void)receiveNotification2:を実行
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification2:) name:@"P2" object:nil];
  //通知を受信して-(void)receiveNotification3:を実行
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification3:) name:@"P3" object:nil];
     //通知を受信して-(void)receiveNotification4:を実行
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotification4:) name:@"P4" object:nil];
     }
//カウンタの動作を記述
-(void)receiveNotification1:(NSNotification *) notification {
    count++;
    countText.text = [NSString stringWithFormat:@"%d",count];
}
//メッセージ表示の動作を記述
-(void)receiveNotification2:(NSNotification *) notification {
    mText.text = [NSString stringWithFormat:@"Notification OK"];
}
//スライダの値を表示する動作を記述
-(void)receiveNotification3:(NSNotification *) notification {
    NSString *valueF = [[notification userInfo] objectForKey:@"KEY1"];
    sliderValue.text = valueF;
    }
//テキストを表示する動作を記述
-(void)receiveNotification4:(NSNotification *) notification {
    NSString *textV = [[notification userInfo] objectForKey:@"KEY2"];
    textF.text = textV;
}
...
@end