Table View Controllerのプロトタイプセルの上にあるビューの高さを設定しようとしています。 IBを使用して高さ(サイズインスペクター)を設定し、61に設定します(緑色のビューは「ヘッダー」ビューです)。
しかし、アプリを実行するたびに、その高さは568.0
になります。テーブルビューコントローラーのビューにtestUIView
というIBOutletがあります。println("testUIView Height->\(testUIView.frame.height)")
で、実際には実行時に568.0
になります。
実行時の高さを示すスクリーンショットは次のとおりです。
だから私の質問は次のとおりです:実行時に61になるようにビューの高さを設定するにはどうすればよいですか?
override func viewWillLayoutSubviews()
内でそのheightプロパティを設定しようとしましたが、高さtestUIView.frame.height = CGFloat(61.0)
に値を割り当てることができませんでした。
どんな助けも大歓迎です!前もって感謝します!
乾杯!
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
}
Swift 3/Xcode 8:
これをviewDidLoad()
に追加します:
let HEADER_HEIGHT = 100
tableView.tableHeaderView?.frame.size = CGSize(width: tableView.frame.width, height: CGFloat(HEADER_HEIGHT))
楽しい!
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
}
}
受け入れられた答えは、実際には質問に答えません。代わりに、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を使用してサブビューとその他の制約を追加してください。