web-dev-qa-db-ja.com

SwiftでtableViewヘッダーの高さを設定する

Table View Controllerのプロトタイプセルの上にあるビューの高さを設定しようとしています。 IBを使用して高さ(サイズインスペクター)を設定し、61に設定します(緑色のビューは「ヘッダー」ビューです)。

header view

しかし、アプリを実行するたびに、その高さは568.0になります。テーブルビューコントローラーのビューにtestUIViewというIBOutletがあります。println("testUIView Height->\(testUIView.frame.height)")で、実際には実行時に568.0になります。

実行時の高さを示すスクリーンショットは次のとおりです。

enter image description here

だから私の質問は次のとおりです:実行時に61になるようにビューの高さを設定するにはどうすればよいですか?

override func viewWillLayoutSubviews()内でそのheightプロパティを設定しようとしましたが、高さtestUIView.frame.height = CGFloat(61.0)に値を割り当てることができませんでした。

どんな助けも大歓迎です!前もって感謝します!

乾杯!

22
idelara

UITableViewの代わりにヘッダーを使用する場合は、Interface Builderで別のプロトタイプセルを設計し、UITableViewCellに基づいてカスタムクラスを作成し、クラスインスペクターのInterface Builderでプロトタイプセルに割り当てます。

次に、コントローラーで使用します

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?

その関数では、実際にはテーブルビューから再利用可能なセルを作成しますが、ヘッダー用に作成したカスタムセルとしてキャストします。通常のUITableViewCellのようなすべてのプロパティにアクセスでき、セルのビューを返すだけです。

return cell.contentView

使用する別の方法は

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 61.0
}

これは自明です。

Swift 3.0.1

public override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 61.0
}
55
Fred Faust

Swift 3/Xcode 8:

これをviewDidLoad()に追加します:

let HEADER_HEIGHT = 100
tableView.tableHeaderView?.frame.size = CGSize(width: tableView.frame.width, height: CGFloat(HEADER_HEIGHT))

楽しい!

19
Nick Ivanov

In Swift 4.1およびXcode 9.4.1

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
     if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
        return 75.0
      } else {
        return 50.0
      }
}
1
iOS

受け入れられた答えは、実際には質問に答えません。代わりに、SECTIONヘッダーを使用して代替手段を提供します。この質問には他の人が回答しましたが、ここでいくつかの指示を加えて回答を複製します。


ビューの読み込み

テーブルビューはiPhoneと同じくらい古いため、必要な操作を強制する必要がある場合があります。

まず、ヘッダーをロードし、その高さを手動で設定する必要があります。そうしないと、ビューの高さが必要以上に高くなります。 viewDidLayoutSubviewsコールバックでこれを行います。

lazy var profileHeaderView: ProfileHeaderView = {
    let headerView = ProfileHeaderView()
    return headerView
}()

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    sizeHeaderToFit()
}

private func sizeHeaderToFit() {
    profileHeaderView.setNeedsLayout()
    profileHeaderView.layoutIfNeeded()

    var frame = profileHeaderView.frame
    frame.size.height = profileHeaderView.calculateHeight()
    profileHeaderView.frame = frame

    tableView.tableHeaderView = profileHeaderView
}

ご覧のとおり、私はビューを遅延変数に入れたいです。これにより、それらが常に作成されますが、使用を開始したときのみです。

また、私は高さを計算していることがわかります。場合によっては、高さが固定されているため、フレームの高さをハードコードされた値に設定することができます。


いくつかの優先順位を設定

デバッガーにいくつかの制約警告が表示される可能性があります。これは、上記で指定したサイズを使用する前にテーブルビューが最初に0x0サイズを強制するために発生します。現時点では、制約とビューの高さが互いに競合しています。

これらをクリアするには、制約の優先順位を設定するだけです。最初に、ヘッダービューコンポーネントを別のビュー内にラップする必要があります(通常、これはヘッダービューに対して常に行います)。これにより、ヘッダービューでの制約の管理がはるかに簡単になります。

次に、最下位の制約優先度を高く設定する必要があります。

containerView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
containerView.setContentHuggingPriority(.defaultHigh, for: .vertical)

より完全な例:

[〜#〜] warning [〜#〜]:ビューをレイアウトするためのガイドとしてまだ役立つと思いますが、ペン先またはストーリーボードを使用してビューを作成する場合は、このコードを使用しないでください。

class ProfileHeaderView: UIView {
    lazy var containerView: UIView = {
        let view = UIView()
        return view
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupLayout()
    }

    required init?(coder aDecoder: NSCoder) {
        // We do this because the view is not created using storyboards or nibs.
        fatalError("init(coder:) has not been implemented")
    }

    private func setupLayout() {
        self.addSubview(containerView)

        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        containerView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        containerView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        containerView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        containerView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
        containerView.setContentHuggingPriority(.defaultHigh, for: .vertical)

        // Set the rest of your constraints against your containerView not self and add your subviews to your containerView not self
    }
}

以下は、スナップキットを使用して設定された制約の例です。

containerView.snp.makeConstraints() { make in
    make.top.equalTo(self.snp.top)
    make.leading.equalTo(self.snp.leading)
    make.trailing.equalTo(self.snp.trailing)
    make.bottom.equalTo(self.snp.bottom).priority(.high)
}

制約をcontainerViewではなくselfに追加し、containerViewを使用してサブビューとその他の制約を追加してください。

0
Kubee