UITableViewで編集モードに入るとセルが右へスライドしますが
その時カスタムセルが画面外へはみだしたり、かぶってしまうという問題の対処法。


結論から言うと、自作したカスタムセルクラスのlayoutSubviewsメソッドでFrameを直書きで指定していたことが原因でした。
その時のコードはこちら。
- (void)layoutSubviews {
[super layoutSubviews];
CGRect baseRect = CGRectInset(self.contentView.bounds , 10, 5);
CGRect rect = baseRect;
rect.size.width = 140 ;
rect.size.height = 12;
leftUpper.frame = rect;
rect.origin.x += 10;
rect.origin.y += 14;
rect.size.width = 130 ;
rect.size.height = 20;
left.frame = rect;
rect.origin.x = 160 ;
rect.size.width = 150 ;
right.frame = rect;
rect.origin.y = 5;
rect.size.height = 12;
rightUpper.frame = rect;
} |
テーブルビューの編集ボタンを押した時や、テーブルビューをスクロールさせて画面外にあるセルが画面内に表示されるタイミングでこのlayoutSubviewsが呼ばれますが、ここでセルサイズの変更に対応できないコードを書いていました。
コードを見ていくと
CGRect baseRect = CGRectInset(self.contentView.bounds , 10, 5); CGRect rect = baseRect; |
ここではCGRectInset(self.contentView.bounds , 10, 5);でセルのフレームからx方向に10px、y方向に5px内側の長方形にあたるFrameを取得しています。
デフォルトのテーブルビューセルは(0,0, 320, 44)なのでここでは(10, 5, 300, 33)のフレームになります。
rect.size.width = 140 ; rect.size.height = 12; leftUpper.frame = rect; rect.origin.x += 10; rect.origin.y += 14; rect.size.width = 130 ; rect.size.height = 20; left.frame = rect; |
次に取得したフレームに対してCGSizeに変更をかけたものを左上のラベルのフレームとしてセット。
このフレームは(10, 5, 140, 12)になります。
左のラベルにはrect.origin.x += 10で原点を10px右へずらし、rect.origin.y += 14で14px下へずらして幅、高さを指定しなおしたフレームをセット。
rect.origin.x = 160 ; rect.size.width = 150 ; right.frame = rect; rect.origin.y = 5; rect.size.height = 12; rightUpper.frame = rect; |
問題はここです。rect.origin.x = 160; rect.size.width=150; と指定しているため、セルサイズの変更に対応できていません。
変更ボタンを押した場合、セルの原点が右へずれてくるので、もし右側のラベルを画面内におさめたいなら、右側のラベルの原点をセルの原点が移動した分だけ左をずらしてやらなければなりません。
最終的にはこうなりました。
- (void)layoutSubviews {
[super layoutSubviews];
CGRect baseRect = CGRectInset(self.contentView.bounds , 10, 5);
CGRect rect = baseRect;
rect.size.width = (baseRect.size.width*0.75 - 88) ;
rect.size.height = 12;
leftUpper.frame = rect;
rect.origin.x += 10;
rect.origin.y += 14;
rect.size.width = (baseRect.size.width - 88) ;
rect.size.height = 20;
left.frame = rect;
rect.origin.x = (baseRect.size.width - 78) ;
rect.size.width = 88 ;
right.frame = rect;
rect.origin.y = 5;
rect.size.height = 12;
rect.origin.x = (baseRect.size.width - 108) ;
rect.size.width = 120;
rightUpper.frame = rect;
} |
編集ボタンを押した場合に右ラベルが画面外にはみでないようにして、かつ、左側のラベルともかぶらないように設定する必要があるので、各ラベルのorizin.xとsize.widthを動的に変更しています。
各ラベルの背景色を別々の目立つ色にして動きをみていくと設定がしやすかったです。
でも正直めんどくさい。
設定後はこんな感じ。


関連のあるアプリ
タグ: iPachi, iphone, objecti, objective-c, UITableView, UITableViewCell, アプリ, セル, パチスロ, リリース, 収支, 対処法, 高さ



3月 13th, 2009 at 5:51 PM
いつも参考にさせて頂いてます。お忙しいところ申し訳ありませんが、時間のあるときで結構ですのでご享受いただければ幸いです。
UITableViewでひとつのcellのCell content部分に表示する文字数が多い場合は「...」で表示が省略されると思います。これを全部表示させることは簡単にできないでしょうか? 詳細画面でスタイルをグループにして、それぞれのデータをcellに表示させたいのですが、この場合、やはりUITextのサブビューかなにかを作るしかないのでしょうか?
Adress Bookの住所表示部のイメージなんですが、それぞれのcellに表示されるTextデータの長さがバラバラの場合はやはり文字数を数えてcellの高さを設定しているのでしょうか?
何か簡単な方法をご存知でしたらお教え頂ければ幸いです。
3月 14th, 2009 at 1:34 AM
>いきちゃんさん
僕もUITableViewCellのリファレンス等を漁ってみましたが、どうやらプロパティ等で簡単に設定する方法はないみたいです。
方法としては,やはりカスタムセルを用意して、そこにUIlabelをセットし、labelのnumberOfLinesプロパティに0を設定。カスタムセルのlayoutSubviewsメソッドで、[label sizeToFit]としてやれば、labelに関しては入力文字数分行数が拡張されるはずです。
同メソッド内で文字数をカウントし、Cellのサイズを調整してやるしか僕の知る範囲では動的にセルサイズを変更する方法はありません。
あまり参考にならない回答で申し訳ないです。
3月 14th, 2009 at 7:43 AM
>daichiさん
お忙しい中ありがとうございました。やはりそれしかないですね。もしかしたらプロパティをいじれば実現できるのか?と思っていましたが.....。
iPhone SDKが進化してくれるともっと楽にアプリを作れるのでしょうがまだまだ発展途上ですね。いろんなところでも書かれていますが、「こんなことするのにここから作らなければならないの?」という感じのところがまだまだありますね....。特に私のようなノンプログラマーにはiPhoneアプリ開発は敷居が高いです。
でも94年に初めてネット接続した時のわくわく感に似たものがあります。資料も少なく、情報もなく手探りで一歩一歩前に進む感覚です。ただ、当時と違うのはこうしてdaichiさんのように知識のある方にご相談できるところです。ネットはすごいですね。
今後ともよろしくお願いします。ありがとうございました。やってみます。
3月 19th, 2009 at 10:58 AM
>daichiさん
開発の合間に、有料でかまわないのでアドバイスを頂くことは可能でしょうか? 私がどうしてもノンプログラマーのためと、あまりにも資料がすくないためにあと1歩でできないことがいくつかあります。daichiさんのアプリに比べればたししたものではないのですが、仕事に使いたいもので開発したいものがかなりあります。いろいろ見て回ったり、質問したりしていますが、daichiさんの回答が一番分かりやすく的を得ていると感じています。直接メールでも頂ければ幸いです。