2015-10-05 11 views
13

私は、ユーザーがオブジェクトのスクロールリストをブラウズし、プッシュセグを使用して特定のオブジェクトの詳細をドリルすることができる典型的なマスターディテールアプリを持っています。スクロールマスターリストは、プロトタイプのセルで構築されたUITableViewであり、詳細シーンは固定数のセクションとセルを持つ静的なUITableViewです。静的テーブルを持つ動的型と自己サイジングセル

私は、ユーザがベースのフォントサイズを変更できるように、私のアプリにダイナミックタイプとセルフサイジングセルを実装したいと思います。これまでは、自動レイアウトを使用し、各ラベルの行数を0に設定し、tableView.rowHeight = UITableViewAutomaticDimensionを設定することで、プロトタイプセルのスクロールリストでセルフサイジングセルを作成することに成功しました。各プロトタイプセルの高さは、内のテキストのサイズ

しかし、私は静的なテーブルビューで同じ効果を達成することはできません。カスタムセルを使用する場合でも組み込みのセルタイプを使用する場合でも、フォントは拡大/縮小されますが、セルの高さは変化しません。

私の質問は実際に2つの質問です:1)私は私のプロトタイプのテーブルビューで行ったように、静的なテーブルビューでセルフサイジングセルを実装することは可能ですか? 2)最初の質問に対する答えが「いいえ」の場合、静的なテーブルビューセル内のラベルの高さを測定し、セルの高さを適切に調整するコードを作成するにはどうすればよいですか?

ありがとうございました!

答えて

1

昨日投稿した質問に回答していただき、ありがとうございます。残念なことに(おそらくiOSプログラマーとしての経験がないため)、私はsystemLayoutSizeFittingSize(UILayoutFittingCompressedSize)アプローチを動作させることができませんでした。いくつかの試行錯誤の後、しかし、私が動作しているように異なる方法が見つかりました:これのストーリーボード側

import UIKit 

class MasterTVC: UITableViewController { 
    @IBOutlet weak var staticCustomCellLabel: UILabel! 

    //viewDidLoad 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.tableView.estimatedRowHeight = 44.0 

     staticCustomCellLabel.text = "This is the text for the static custom cell label; This is the text for the static custom cell label; This is the text for the static custom cell label" 

     //Register handleDynamicTypeChange in observer: self 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleDynamicTypeChange:", name: UIContentSizeCategoryDidChangeNotification, object: nil) 
    } 

    //deinit 
    deinit { 
     NSNotificationCenter.defaultCenter().removeObserver(self) 
    } 

    //handleDynamicTypeChange 
    //called when user changes text size in Settings > General > Accessibility > Larger Text 
    //or Settings > Display & Brightness > Text Size 
    func handleDynamicTypeChange(notification: NSNotification) { 
     staticCustomCellLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) 

     self.tableView.reloadData() 
    } 

    //tableView:heightForRowAtIndexPath 
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
     return UITableViewAutomaticDimension 
    } 
} 

を、セットアップは、次のプロパティを持つ単一のテーブルビューコントローラで始まります。

  • クラス:MasterTVC(私のカスタムクラス);
  • は、初期View Controllerと指定されています。
  • 内容:静的セル;
  • スタイル:グループ化された
  • セクション:1.

セクション-1:

  • 行:1。

テーブルビューのセル:

  • スタイル:カスタム(設定で文字サイズを変更するときに、ここで基本を使用すると、ラベルが表示されなくなり)。
  • UILabelを含んでいます。

UILabelのようにさらに構成されている:

  • フォント:ボディ(ダイナミック型スタイル)。
  • 行:0;
  • コンテンツビューの上端、下端、左端、および右端に4辺すべてを固定しました(それぞれの制約8,8,15,15を使用しました)。
  • カスタムクラスコードの@IBOutletを使用します。

これは、私がXcode 7のiOS 9と自動レイアウトを有効にしたSwift 2を設計するときに役立ちました。興味深いのは、テキストサイズの変更に即座に応答するために使用されるNSNotificationCenterコードを取り除くと、セルフサイジングセルのコードは基本的に2つの行である:viewDidLoadでestimatedRowHeightを設定し、tableView:heightForRowAtIndexPathからUITableViewAutomaticDimensionを返すことです。

私は、これらの結果に基づいて、私の元の質問に対する答えは、1)はい、 2)1を参照してください。

1

これは静的なテーブルですので、あなたが彼らにIBOutletsを作成する必要がありますので、あなたは私はこのような配列にそれらを保持したい、細胞をデキューすることはできません。

@IBOutlet var cells: [UITableViewCell]! 

次に、あなたがしますheightForRowAtIndexPathを実装し、サイズを計算する必要があります。

var rowSizes: [Int: CGFloat] = [:] 

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return calculateHeightForCell(indexPath) 
} 

func calculateHeightForCell(indexPath: NSIndexPath) -> CGFloat { 

    // check if we already calculated the height 
    if let height = rowSizes[indexPath.row] { 
     return height 
    } 

    // else, calculate it 
    let cell = cells[indexPath.row] 

    let size = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) 

    rowSizes[indexPath.row] = size.height 

    return size.height 
} 

rowSizesがキャッシュのように機能し、それは、行の高さを保持するので、彼らは一度だけ計算されます。フォントサイズを変更するときは、rowSizeを空にしてテーブルをリフレッシュするだけで、再度計算されます。

15

静的テーブルビューは、Interface Builderで設定された行の高さを返します。 tableView.rowHeightの設定は完全に無視されているようです。これは明らかにUIKitのバグです。

これを修正するには、単に-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPathを上書きし、UITableViewAutomaticDimensionを返すだけです。

+0

ありがとうございました! – mangerlahn

+0

delegate関数を使用する代わりに 'tableView.rowHeight'を設定できますか? – BallpointBen

+0

@BallpointBen私の答えで2番目の文章をお読みください。 – Andy

3

まずUITableViewAutomaticDimensionの仕事はあなたがすべての左、右、下、及び電池容器のビューに対するトップ制約を追加したことを確認させるために、あなたのクラスで

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return UITableViewAutomaticDimension 
} 

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return UITableViewAutomaticDimension 
} 

セカンドをこの2つの機能を追加します。また、ラベルの行数をゼロに設定することも忘れないでください。

関連する問題