28384
以下のソースサンプルのように、カスタムビューのボタンのaddTargetメソッドをViewControllerに書きたいのですが、セレクターのメソッドが呼ばれません。

《試したこと》

  1. カスタムビュー内にaddTargetメソッドを書いて、引数targetをnilにしてtapButton:を呼び出すように書くと動きましたが、警告が出ますし、tapButtonというメソッド名をViewController側で自由に決めることができないので、違うと思います。
  2. サイズの関係で動かない場合もあるということで、backView、descriptionView、descriptionView.buttonの各frameをNSLogで表示させましたが、buttonだけ{0,0},{0,0}でした。

サンプルソースの(※)でもbutton.backgroundColorへの設定が反映されていませんし、どうやらbuttonのプロパティにアクセスできていないことが原因と考えましたが、理由が分かりません。

何かおかしなことをしてしまっているのでしょうか。

* * *

カスタムビュー

```

    @interface DescriptionView : UIView
    
    @property (weak) UIButton *button;
    @property NSString *buttonStr;
    
    @end
    
    @implementation DescriptionView
    
    - (void)drawRect:(CGRect)rect {
        UIButton *closeButton = [UIButton buttonWithType:UIButtonTypeSystem];
        [closeButton setTitle:_buttonStr forState:UIControlStateNormal];
        closeButton.frame = CGRectMake(0, CGRectGetMaxY(rect)-40, rect.size.width, 40);
        _button = closeButton;
        [self addSubview:closeButton];
    
    }
    
```

ViewController

```

    @implementation ViewController
    
    - (void)viewDidLoad {
        // TableViewを置いてます。ちなみにサイズは画面サイズ。
    
        // カスタムビューの背面にくる土台ビュー
        UIView *backView = [[UIView alloc]initWithFrame:_tableView.frame];
        backView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4];
        backView.alpha = 0;
        backView.tag = VIEW_INFO;
        [self.view addSubview:backView];
    
        //カスタムビュー
        DescriptionView *descriptionView = [[DescriptionView alloc]init];
        descriptionView.buttonStr = @"next"; // <-これは反映される
        descriptionView.button.backgroundColor = [UIColor yellowColor];　// <-(※)これは反映されない
        [descriptionView.button addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside];
        descriptionView.frame = CGRectInset(_tableView.frame, 20, 30);
        [backView addSubview:descriptionView];
        //だんだん表す
        [UIView animateWithDuration:0.8 animations:^{
            backView.alpha = 1;
        }];
    }
    
```
CC BY-SA 3.0
2016-08-19T03:59:02.317
28364
2016-08-20T03:28:52.623
2016-08-20T03:23:16.947
5519
17254
question
ios objective-c
カスタムビュー上のUIButtonのタップアクションをViewControllerで設定したい
ボタンを`drawRect:`で生成しているのが原因だと思います。`drawRect:`はシステムからビューの表示のために何度も呼ばれるメソッドです。現在のコードでは、`drawRect:`が呼ばれるたびに新しくボタンが作られて上書きされています。  
つまり`viewDidLoad`でアクションメソッドを設定したボタンのインスタンスは、`drawRect:`が呼ばれることで上書きされて、別のボタンに変わってしまいます。

`viewDidLoad`と`drawRect:`にブレークポイントやログを出力するなどして、どのような順序で呼ばれているか、確かめてみるとわかると思います。

解決法としては、ボタンの生成を`init`などに移して、上書きされないようにします。
CC BY-SA 3.0
2016-08-20T03:28:52.623
28384
2016-08-20T03:28:52.623
5519
28364
answer