iOS7でUITableViewCell上のボタンをタップしたら落ちた

##こんなエラーが起きた
大分略していますがこんな感じのコードを書いて、UITableViewCell上のボタンをタップした時の処理を実行してたのですが、

```objective-c:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  //~ 略 ~
  cell = [[RensouCell alloc]
             initWithStyle:UITableViewCellStyleDefault
           reuseIdentifier:CellIdentifier];

  // ボタンタップ時のイベント感知
  [cell.likeButton addTarget:self
                      action:@selector(onClickLikeButton:)
            forControlEvents:UIControlEventTouchUpInside];
  //~ 略 ~
}

// ボタンタップ時に実行される処理
- (void)onClickLikeButton:(UIButton *)button
{
  // タップされたボタンから、対応するセルを取得する
  RensouCell *cell = (RensouCell *)[button superview];
  //~ 略 ~
  [cell likeRensou];
}
```

iOS7で実行してみたら、こんなエラーを出して落ちてしまいました。（iOS6以前だと普通に動く）

```
[UITableViewCellScrollView likeRensou]: unrecognized selector sent to instance 0x9b453e0
```

「UITableViewCellScrollView に、likeRensou なんてメソッド無いよ！」というエラーなのですが、そもそもUITableViewCellScrolView ってどこから出てきたんだよ…、という感じでした。(;´Д｀)


##原因
ぐぐったら以下の記事で解説されていました。
参考：[iOS7 では UITableViewCell の subviews階層が変更されている | objc-Lovers](http://objc-lovers.com/archives/166)

なるほど階層が変わったんですね。確かにこれだと、タップされたUIButtonのsuperviewを取得すると、UITableViewCellScrollViewになりますわ…。

####追記
twitterで指摘されて気づいたのですが、UITableViewCellにUIButtonを配置する際は、selfにaddSubviewするんじゃなくて、self.contentViewに対してaddSubviewするのが正しいようです…orz
参考：[ynumerator_blog: Custome UITableViewCellの[self addSubview]と[self.contentView addView]の違い](http://ynumerator.blogspot.jp/2013/01/custome-uitableviewcellself.html)

正しいやり方でやっていると、UIButtonのsuperviewはUITableViewCellContentになります。この辺のviewの構造については、以下の図が分かりやすいです。
参考：[iOS6とiOS7のUITableViewCell構造の違い](http://www.slideshare.net/techblogyahoo/2-ios7-workshopmigration/25)


##解決策
調べていくうちに、今までやっていたsuperviewを使って対応するUITableViewCellを取得するやり方は、元々推奨されていないという事が分かったので、ガラッと方法を変えてUIEventを使うようにしました。これでばっちり！！

```objective-c:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  //~ 略 ~
  cell = [[RensouCell alloc]
             initWithStyle:UITableViewCellStyleDefault
           reuseIdentifier:CellIdentifier];

  // ボタンタップ時のイベント感知
  [cell.likeButton addTarget:self
                      action:@selector(onClickLikeButton:event:)
            forControlEvents:UIControlEventTouchUpInside];
  //~ 略 ~
}

// ボタンタップ時に実行される処理
- (void)onClickLikeButton:(UIButton *)button event:(UIEvent *)event
{
  // タップされたボタンから、対応するセルを取得する
  NSIndexPath *indexPath = [self indexPathForControlEvent:event];
  RensouCell *cell = (RensouCell *)[self.tableView cellForRowAtIndexPath:indexPath];
  //~ 略 ~
  [cell likeRensou];
}

// UIControlEventからタッチ位置のindexPathを取得する
- (NSIndexPath *)indexPathForControlEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint p = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:p];
    return indexPath;
}
```

参考：[Objective-C:UITableViewCell上に配置したButtonのタップを感知する方法 - Qiita [キータ]](http://qiita.com/tomochang/items/8770c1963afd8157e56b)


##解決策その2
上で挙げたような修正が大変な場合は、オススメは出来ませんが、以下のような修正方法もあるらしいです。一応紹介。

参考：[既存アプリのiOS 7対応 | iOS 7エンジニア勉強会](http://www.slideshare.net/techblogyahoo/2-ios7-workshopmigration/27)


##というわけで
無事修正したものを再申請できました！！早く審査通らないかな(´ω`)