##こんなエラーが起きた
大分略していますがこんな感じのコードを書いて、UITableViewCell上のボタンをタップした時の処理を実行してたのですが、
-(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
なるほど階層が変わったんですね。確かにこれだと、タップされたUIButtonのsuperviewを取得すると、UITableViewCellScrollViewになりますわ…。
####追記
twitterで指摘されて気づいたのですが、UITableViewCellにUIButtonを配置する際は、selfにaddSubviewするんじゃなくて、self.contentViewに対してaddSubviewするのが正しいようです…orz
参考:ynumerator_blog: Custome UITableViewCellの[self addSubview]と[self.contentView addView]の違い
正しいやり方でやっていると、UIButtonのsuperviewはUITableViewCellContentになります。この辺のviewの構造については、以下の図が分かりやすいです。
参考:iOS6とiOS7のUITableViewCell構造の違い
##解決策
調べていくうちに、今までやっていたsuperviewを使って対応するUITableViewCellを取得するやり方は、元々推奨されていないという事が分かったので、ガラッと方法を変えてUIEventを使うようにしました。これでばっちり!!
-(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 [キータ]
##解決策その2
上で挙げたような修正が大変な場合は、オススメは出来ませんが、以下のような修正方法もあるらしいです。一応紹介。
参考:既存アプリのiOS 7対応 | iOS 7エンジニア勉強会
##というわけで
無事修正したものを再申請できました!!早く審査通らないかな(´ω`)