2016-04-06 25 views
3

私は、そのセルの高さが表示されているテキストの量に応じた大きさでのUITableViewを作成しようとしています。 heightForRowAtIndexPathが利用可能であり、私は以下のコードを使用してUILabelするために必要な必要なサイズを取得することができ、これは、十分に簡単に思えました。しかし、この方法は私には非常に奇妙な選択を思わセルの内容に基づいて、私はできない大きさcellForRowAtIndexPath前に呼び出されます。コンテンツに基づいてセルの高さを動的にサイズ調整する "ベストプラクティス"の方法は何ですか?また動的にサイズ変更のUITableViewCellハイツ

、なぜAppleはheightForRowAtIndexPathメソッドがcellForRowAtIndexPath後に呼び出されることはありませんでしたか?

私はラベルのために必要な高さを決定するためにcellForRowAtIndexPathで次のように使用していますが、私はdequeReusableCellWithIdentifierは(私の知る限り)メソッドで呼び出すことはできませんので、heightForRowAtIndexPathにこれを移動するかどうかはわかりません。

func getRequiredLabelHeight(label: UILabel, text: String, font: UIFont) -> CGFloat { 
    label.numberOfLines = 0 
    label.lineBreakMode = .ByWordWrapping 
    label.font = font 
    label.text = text 
    label.sizeToFit() 

    return label.frame.height 

} 

新しいラベルのサイズに基づいて、初期サイズ(1行のラベルでヒンジしている)からセルのサイズを増やしたいので、次のセルの高さが必要です。行の任意の長さ)

self.cellHeight = getRequiredLabelHeight(commentCell.commentTextLabel, text: allComments![indexPath.row].text, font: UIFont(name: "Avenir", size: 16.0)!) + commentCell.bounds.height - commentCell.commentTextLabel.bounds.height 

ありがとう!

EDIT 私の質問はラベルのサイズ変更に関するものではありません。私が提供したコードはそれを行います。問題はセルの高さが一定ではないことです。内容に基づいてテーブル全体で変化するので、私はスタティックtableview.rowHeightを使用することはできません。セルの高さをcellForRowAtIndexPathから変更できないため、コンテンツがセルに収まりません。 UILabelのフレームがthan tableview.rowHeight大きくなると

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    let commentCell: CommentTableViewCell = tableView.dequeueReusableCellWithIdentifier("commentTableViewCell", forIndexPath: indexPath) 
     as! CommentTableViewCell 

    commentCell.commentTextLabel.textColor = Utils.hatchliTextDark 
    commentCell.commentTextLabel.font = UIFont(name: "Avenir", size: 16) 

    self.cellHeight = getRequiredLabelHeight(commentCell.commentTextLabel, text: allComments![indexPath.row].text, font: UIFont(name: "Avenir", size: 16.0)!) + commentCell.bounds.height - commentCell.commentTextLabel.bounds.height 

    commentCell.commentTextLabel.frame = CGRectMake(commentCell.commentTextLabel.frame.origin.x, commentCell.commentTextLabel.frame.origin.y, commentCell.commentTextLabel.frame.width, self.cellHeight) 
    commentCell.handleTextLabel.text = String(allComments![indexPath.row].creatorHandle) 
    commentCell.votesTextLabel.text = String(allComments![indexPath.row].votes) 
    commentCell.commentTextLabel.text = allComments![indexPath.row].text 
    commentCell.setMargin() 

    return commentCell 

} 

そう、それは表示されません:たとえば、ここに私はcellForRowAtIndexPath(一言で言えば)です。したがって、行の高さがheightForRowAtIndexPathからセル毎にリサイズする必要

+0

と呼ばれているであることを確認してください。テーブルビューは、現時点で表示されている少数のセルを表示する必要がある前に、完全な高さを知る必要があります。 – rmaddy

+1

セルのサイズを自動的に変更するオートレイアウトを使用していますか?そうでなければ、 'tableView:heightForRowAtIndexPath:'メソッドの現在のコードは何ですか?あなたは次のような答えを見たことがありますか:http://stackoverflow.com/q/20068849/558933、http://stackoverflow.com/q/25180443/558933、http://stackoverflow.com/q/27374612/558933 –

+0

は、セル単位でUITableViewのセルの高さを自動レイアウトできますか? – treyhakanson

答えて

2

SOLUTION

Iが見出さ溶液が少し危ないである(私は仮定)が、私は他の方法が表示されません。基本的に、私はUILabelの幅が表示されるテキストの文字列とフォントの特性を有することに加えて、取り上げる画面のどのような割合は知っています。これらの要因に基づいて、私は必要とされているUILabelのどのような高さを決定するために、次のコードを使用することができ、かつ、細胞自体が生成される前に、デフォルトのセルとラベルの高さを加味することによって、私の必要なセルの高さを見つけることができます。

// width of string as a particular font in one line 
func getStringSizeForFont(font: UIFont, myText: String) -> CGSize { 
    let fontAttributes = [NSFontAttributeName: font] 
    let size = (myText as NSString).sizeWithAttributes(fontAttributes) 

    return size 

} 

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    // get the string size 
    let stringSizeAsText: CGSize = getStringSizeForFont(UIFont(name: "Avenir", size: 16.0)!, myText: allComments![indexPath.row].text) 

    // label width and height are hardcoded here, but can easily be made dynamic based on the screen width 
    // and the constant proportion of the width the UILabel will take up 
    // example: 
    // let labelWidth: CGFloat = UIScreen.mainScreen().bounds.width * widthProportion 
    // originalLabelHeight can be hardcoded or made dynamic; I'm going to leave my hardcoded because I'll be leaving the height 
    // the same across all devices 

    let labelWidth: CGFloat = 259.0 
    let originalLabelHeight: CGFloat = 20.5 

    // the label can only hold its width worth of text, so we can get the ammount of lines from a specific string this way 
    let labelLines: CGFloat = CGFloat(ceil(Float(stringSizeAsText.width/labelWidth))) 

    // each line will approximately take up the original label's height 
    let height = tableView.rowHeight - originalLabelHeight + CGFloat(labelLines*stringSizeAsText.height) 

    return height 

} 
+2

stringSize.width/labelWidthは正確な行数。改行モードが.ByWordWrappingの場合、ラベルの行末に空白が入ります。ただし、計算されたstringSizeはこれらの空白を考慮しません。 これらの空白の幅の合計がlabelWidthより大きい場合、計算された行数は間違っているはずです。 – Mark

+0

あなたは正しいですが、これは私が時々実行していた問題です。私の目的のために、それは多くのトラブルを引き起こしませんでしたが、それは間違いなく、このソリューションを実装するために探している誰もが考慮する必要があります – treyhakanson

0

オーバーライドのfuncのtableView(のtableView::のUITableView、estimatedHeightForRowAtIndexPath indexPath:1)あなたのこのような場合のために、私の意見では最良の選択肢は次のようになりNSIndexPath) - > CGFloat { 戻りUITableViewAutomaticDimension }

...とheightForRowAtIndexPath」で"in dicateあなたは高さを計算した場合、別のオプションは次のようになり

2)「UITableViewAutomaticDimensionを返す」:

「cellForRowAtIndexPath」であなたは「self.tableView.rowHeight」の値を変更することができるはずです。 このオプションは、TableViewのnibが異なる場合にも便利です。

+0

これは、セルが完全に制約されている場合のみ動作します。私はプログラム的に細胞を構築していたので、細胞の変化のために私の場合には制約を設定できませんでした。後見では、さまざまな状況で使用するために1つのフレキシブルセルをプログラムで作成するのではなく、さまざまな完全に制約のあるペン先からセルをロードするのが最善の方法でした。 – treyhakanson

-1

私はこのチュートリアルを読んで、1行のコードを使って、uitableviewセルの内容をラベルの内容でサイズ変更することができました。

//===== 
https://www.raywenderlich.com/129059/self-sizing-table-view-cells 
//===== 

のviewDidLoadで

tableView.rowHeight = UITableViewAutomaticDimension 

tableView.estimatedRowHeight = 140 

を追加()とラベル/のTextViewのラインの確認数は `heightForRowAtIndexPath`がcellForRowAtIndexPath``の完全に独立して0

+0

これは、セルのビューが完全に制約されている場合にのみ機能し、ダイナミックにセルを生成していたので、これは私のシナリオでは機能しません。これは、ペン先から完全に拘束されたセルをロードするようなことをするときに機能するということは間違いありません – treyhakanson

関連する問題