[解決済み] iOS 7のUITableViewCellとUITextViewの高さ?
質問
iOS 7で、UITextViewを含むUITableViewCellの高さを計算するにはどうしたらよいでしょうか。
似たような質問でたくさんの回答がありましたが
sizeWithFont:
はすべての解決策に関与しており、このメソッドは非推奨です!
を使わなければならないことは分かっています。
- (CGFloat)tableView:heightForRowAtIndexPath:
を使用しなければならないことは知っていますが、テキスト全体を表示するために必要なTextViewの高さはどのように計算するのでしょうか?
どのように解決するのですか?
まず最初に、テキストがどのようにレンダリングされるかに関して、UITextView と UILabel の間に大きな違いがあることに注意することが非常に重要です。UITextView はすべての境界線にインセットを持つだけでなく、その内部のテキスト レイアウトもわずかに異なっています。
そのため
sizeWithFont:
はUITextViewsのために悪い方法です。
代わりに
UITextView
という関数があります。
sizeThatFits:
のすべての内容を表示するのに必要な最小のサイズを返します。
UITextView
の全ての内容を表示するのに必要な最小のサイズを返します。
以下はiOS 7とそれ以前のバージョンで同じように動作し、現在のところ、非推奨のメソッドは含まれていません。
簡単な解決方法
- (CGFloat)textViewHeightForAttributedText: (NSAttributedString*)text andWidth: (CGFloat)width {
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:text];
CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
return size.height;
}
この関数は
NSAttributedString
で、希望する幅を
CGFloat
で、必要な高さを返す
詳細な解決策
私も最近同じようなことをしたので、私が遭遇した接続された問題に対する解決策も共有しようと思いました。誰かの助けになればと思います。
これははるかに深いもので、以下をカバーします。
-
もちろん: 高さを設定する
UITableViewCell
の内容を完全に表示するために必要なサイズに基づいて、高さを設定することができます。UITextView
- テキストの変更に応答する(そして行の高さの変更をアニメーション化する)
-
カーソルを可視領域内に維持し、ファーストレスポンダーを
UITextView
のサイズを変更する場合UITableViewCell
編集中
静的なテーブルビューで作業している場合、または、既知の数の
UITextView
の数が既知である場合、ステップ 2 をより単純化できる可能性があります。
1. まず、heightForRowAtIndexPathを上書きします。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// check here, if it is one of the cells, that needs to be resized
// to the size of the contained UITextView
if ( )
return [self textViewHeightForRowAtIndexPath:indexPath];
else
// return your normal height here:
return 100.0;
}
2. 必要な高さを計算する関数を定義する。
を追加する。
NSMutableDictionary
(を追加します(この例では
textViews
) をインスタンス変数として
UITableViewController
のサブクラスのインスタンス変数として使用します。
この辞書を使用して、個々の
UITextViews
のようにします。
(そして、そう indexPaths は辞書の有効なキーです。 )
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Do you cell configuring ...
[textViews setObject:cell.textView forKey:indexPath];
[cell.textView setDelegate: self]; // Needed for step 3
return cell;
}
この関数は、今度は実際の高さを計算します。
- (CGFloat)textViewHeightForRowAtIndexPath: (NSIndexPath*)indexPath {
UITextView *calculationView = [textViews objectForKey: indexPath];
CGFloat textViewWidth = calculationView.frame.size.width;
if (!calculationView.attributedText) {
// This will be needed on load, when the text view is not inited yet
calculationView = [[UITextView alloc] init];
calculationView.attributedText = // get the text from your datasource add attributes and insert here
textViewWidth = 290.0; // Insert the width of your UITextViews or include calculations to set it accordingly
}
CGSize size = [calculationView sizeThatFits:CGSizeMake(textViewWidth, FLT_MAX)];
return size.height;
}
3. 編集中のリサイズを可能にする
次の2つの関数では、デリゲートオブジェクトの
UITextViews
に設定されていることが重要です。
UITableViewController
. もし、デリゲートとして他のものが必要な場合は、そこから関連する呼び出しを行うか、適切なNSNotificationCenterフックを使用することで回避することができます。
- (void)textViewDidChange:(UITextView *)textView {
[self.tableView beginUpdates]; // This will cause an animated update of
[self.tableView endUpdates]; // the height of your UITableViewCell
// If the UITextView is not automatically resized (e.g. through autolayout
// constraints), resize it here
[self scrollToCursorForTextView:textView]; // OPTIONAL: Follow cursor
}
4. カーソルを追いながら編集する
- (void)textViewDidBeginEditing:(UITextView *)textView {
[self scrollToCursorForTextView:textView];
}
これによって
UITableView
がUITableViewの可視範囲内にない場合、カーソルの位置までスクロールします。
- (void)scrollToCursorForTextView: (UITextView*)textView {
CGRect cursorRect = [textView caretRectForPosition:textView.selectedTextRange.start];
cursorRect = [self.tableView convertRect:cursorRect fromView:textView];
if (![self rectVisible:cursorRect]) {
cursorRect.size.height += 8; // To add some space underneath the cursor
[self.tableView scrollRectToVisible:cursorRect animated:YES];
}
}
5. インセットの設定による、可視矩形の調整
編集中に
UITableView
の一部がキーボードで覆われることがあります。テーブルビューのインセットを調整しない場合。
scrollToCursorForTextView:
がテーブルビューの下部にある場合、カーソルの位置までスクロールすることができません。
- (void)keyboardWillShow:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0, kbSize.height, 0.0);
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
}
- (void)keyboardWillHide:(NSNotification*)aNotification {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.35];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0, 0.0, 0.0);
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
[UIView commitAnimations];
}
そして最後の部分。
ビューがロードされたら、キーボードの変更に関する通知に登録します。
NSNotificationCenter
:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
この回答が長くなったことで、私に怒らないでください。質問に答えるためにすべてが必要なわけではありませんが、これらの直接関連する問題が役に立つ人が他にいると信じています。
アップデートを行います。
Dave Haupert が指摘したように、私は、(1) と (2) を含めるのを忘れていました。
rectVisible
という関数があります。
- (BOOL)rectVisible: (CGRect)rect {
CGRect visibleRect;
visibleRect.origin = self.tableView.contentOffset;
visibleRect.origin.y += self.tableView.contentInset.top;
visibleRect.size = self.tableView.bounds.size;
visibleRect.size.height -= self.tableView.contentInset.top + self.tableView.contentInset.bottom;
return CGRectContainsRect(visibleRect, rect);
}
また、私が気づいたのは
scrollToCursorForTextView:
には、私のプロジェクトの TextField の 1 つへの直接参照が含まれていることにも気づきました。もし、あなたが
bodyTextView
が見つからない場合は、関数の更新されたバージョンを確認してください。
関連
-
[解決済み] iOSまたはmacOSで、インターネット接続が有効かどうかを確認するにはどうすればよいですか?
-
[解決済み] iOSのステータスバーの文字色を変更する方法
-
[解決済み] ボディの高さをブラウザの高さの100%にする
-
[解決済み] UITextViewのプレースホルダー
-
[解決済み] UITableViewCell、スワイプ時に削除ボタンを表示させる
-
[解決済み] iOS 7でステータスバーとナビゲーションバーがビューの境界を越えて表示される
-
[解決済み] iOS 2.0でのメールアドレス検証のベストプラクティスとは?
-
[解決済み] ARC対応コードにおける「このブロック内で強く[オブジェクト]を捕捉するとretainサイクルになる可能性があります」という警告の修正
-
[解決済み] iOS 7で完全に透明なナビゲーションバーを作成する方法
-
[解決済み] swiftのコード実行のエントリーポイントは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] iOSで画面の幅と高さを取得する方法は?
-
[解決済み】NSAttributedStringはどのように使うのですか?
-
[解決済み] iOS 2.0でのメールアドレス検証のベストプラクティスとは?
-
[解決済み] autolayoutですべてのサブビューに合うようにスーパービューのサイズを変更する方法?
-
[解決済み] ARC対応コードにおける「このブロック内で強く[オブジェクト]を捕捉するとretainサイクルになる可能性があります」という警告の修正
-
[解決済み] iOS 7で完全に透明なナビゲーションバーを作成する方法
-
[解決済み] swiftのコード実行のエントリーポイントは何ですか?