为什么TableView单元中的垂直堆栈视图不动态生成高度?

时间:2020-04-13 14:53:29

标签: ios swift

以下是一张图片,解释了我正在尝试做的事情和所看到的事情:

enter image description here

在每个单元格中获得标题和支持内容可以按预期工作,但是我尝试在UITableViewDataSource委托中使用以下代码进行测试,以查看颜色块进入垂直堆栈视图,但仅显示黄线,使我相信垂直堆栈视图的高度根本没有增加。

我认为问题出在哪里:我将垂直堆栈视图上的约束均设置为0,希望底部0表示它将一直向下下降(例如,从底部,无论底部到底是什么),但也许这不是正确的方法,它实际上将高度限制为0。

    let box1 = UIView()
    box1.frame = CGRect(x: 0, y: 0, width: 400, height: 400)
    box1.backgroundColor = .yellow
    let box2 = UIView()
    box2.frame = CGRect(x: 0, y: 0, width: 400, height: 400)
    box2.backgroundColor = .yellow
    cell.verticalStackView.addArrangedSubview(box1)
    cell.verticalStackView.addArrangedSubview(box2)

注意:堆栈视图的分布为fill equally,间距为4。将分布更改为fill会删除黄线,但不能解决。

我不知道将UITableViewAutomaticDimension添加到表视图行高的位置,所以也许这是解决办法?

2 个答案:

答案 0 :(得分:1)

基于评论-OP似乎解决了该问题...但是,下面的示例可能仍然有帮助。

这是单元xib(蓝色轮廓是堆栈视图的边界):

enter image description here

堆栈视图设置:

enter image description here

注意:为了在设计过程中满足Interface Builder的要求,我为堆栈视图设置了100的高度限制,但将其设置为占位符,以便在运行时将其删除:

enter image description here

结果:

enter image description here

并向下滚动一点:

enter image description here

以下是xib的来源:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
    <device id="retina6_1" orientation="portrait" appearance="light"/>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="261" id="qNz-cd-r4O" customClass="MPCCell" customModule="MiniScratch" customModuleProvider="target">
            <rect key="frame" x="0.0" y="0.0" width="356" height="261"/>
            <autoresizingMask key="autoresizingMask"/>
            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="qNz-cd-r4O" id="rw4-5D-vJu">
                <rect key="frame" x="0.0" y="0.0" width="356" height="261"/>
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="iI3-m2-L2U">
                        <rect key="frame" x="36" y="12" width="284" height="45"/>
                        <subviews>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Headline" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UW8-L7-x4a">
                                <rect key="frame" x="108" y="12" width="68" height="21"/>
                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" red="0.26394423839999998" green="0.44803369050000003" blue="0.76730746029999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstAttribute="bottom" secondItem="UW8-L7-x4a" secondAttribute="bottom" constant="12" id="09x-rj-djb"/>
                            <constraint firstItem="UW8-L7-x4a" firstAttribute="centerY" secondItem="iI3-m2-L2U" secondAttribute="centerY" id="Pjq-kb-VBD"/>
                            <constraint firstItem="UW8-L7-x4a" firstAttribute="top" secondItem="iI3-m2-L2U" secondAttribute="top" constant="12" id="sbt-LW-A1a"/>
                            <constraint firstItem="UW8-L7-x4a" firstAttribute="centerX" secondItem="iI3-m2-L2U" secondAttribute="centerX" id="tbW-Up-s9e"/>
                        </constraints>
                    </view>
                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q2N-gq-ZWR">
                        <rect key="frame" x="36" y="65" width="284" height="44.5"/>
                        <subviews>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Supporting content" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hbx-b0-ZsJ">
                                <rect key="frame" x="8" y="12" width="268" height="20.5"/>
                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" red="0.26394423839999998" green="0.44803369050000003" blue="0.76730746029999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="hbx-b0-ZsJ" firstAttribute="centerX" secondItem="Q2N-gq-ZWR" secondAttribute="centerX" id="KMe-cw-HFN"/>
                            <constraint firstItem="hbx-b0-ZsJ" firstAttribute="leading" secondItem="Q2N-gq-ZWR" secondAttribute="leading" constant="8" id="NGw-fR-eJd"/>
                            <constraint firstItem="hbx-b0-ZsJ" firstAttribute="top" secondItem="Q2N-gq-ZWR" secondAttribute="top" constant="12" id="TLL-g6-Fjq"/>
                            <constraint firstAttribute="trailing" secondItem="hbx-b0-ZsJ" secondAttribute="trailing" constant="8" id="tyG-4i-x2s"/>
                            <constraint firstItem="hbx-b0-ZsJ" firstAttribute="centerY" secondItem="Q2N-gq-ZWR" secondAttribute="centerY" id="yBl-K5-xKl"/>
                            <constraint firstAttribute="bottom" secondItem="hbx-b0-ZsJ" secondAttribute="bottom" constant="12" id="zpZ-83-jqU"/>
                        </constraints>
                    </view>
                    <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="1YZ-yV-ruW">
                        <rect key="frame" x="50" y="117.5" width="256" height="100"/>
                        <constraints>
                            <constraint firstAttribute="height" constant="100" placeholder="YES" id="GVt-mR-ILU"/>
                        </constraints>
                    </stackView>
                </subviews>
                <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                <constraints>
                    <constraint firstItem="Q2N-gq-ZWR" firstAttribute="centerX" secondItem="iI3-m2-L2U" secondAttribute="centerX" id="0X4-Z9-AJY"/>
                    <constraint firstItem="1YZ-yV-ruW" firstAttribute="centerX" secondItem="Q2N-gq-ZWR" secondAttribute="centerX" id="Ba0-yG-ibk"/>
                    <constraint firstItem="iI3-m2-L2U" firstAttribute="top" secondItem="rw4-5D-vJu" secondAttribute="top" constant="12" id="Hcr-2X-7pH"/>
                    <constraint firstItem="Q2N-gq-ZWR" firstAttribute="top" secondItem="iI3-m2-L2U" secondAttribute="bottom" constant="8" id="RGZ-1L-32E"/>
                    <constraint firstItem="1YZ-yV-ruW" firstAttribute="width" secondItem="Q2N-gq-ZWR" secondAttribute="width" multiplier="0.9" id="Rgu-ue-rwv"/>
                    <constraint firstItem="iI3-m2-L2U" firstAttribute="leading" secondItem="rw4-5D-vJu" secondAttribute="leading" constant="36" id="SWp-gQ-CmT"/>
                    <constraint firstItem="1YZ-yV-ruW" firstAttribute="top" secondItem="Q2N-gq-ZWR" secondAttribute="bottom" constant="8" id="eoV-nE-dBM"/>
                    <constraint firstAttribute="trailing" secondItem="iI3-m2-L2U" secondAttribute="trailing" constant="36" id="jB2-qc-ba0"/>
                    <constraint firstItem="Q2N-gq-ZWR" firstAttribute="width" secondItem="iI3-m2-L2U" secondAttribute="width" id="mjX-lH-QBz"/>
                    <constraint firstAttribute="bottomMargin" relation="greaterThanOrEqual" secondItem="1YZ-yV-ruW" secondAttribute="bottom" constant="8" id="okC-Kj-vYa"/>
                </constraints>
            </tableViewCellContentView>
            <connections>
                <outlet property="headlineLabel" destination="UW8-L7-x4a" id="9mT-WA-Leg"/>
                <outlet property="supportLabel" destination="hbx-b0-ZsJ" id="buT-GP-BD7"/>
                <outlet property="vertStackView" destination="1YZ-yV-ruW" id="rSG-Ln-gzU"/>
            </connections>
            <point key="canvasLocation" x="111.59420289855073" y="150.33482142857142"/>
        </tableViewCell>
    </objects>
</document>

,并为表视图控制器和单元格类生成该结果:

//
//  ExampleTableViewController.swift
//  Created by Don Mag on 4/13/20.
//

import UIKit

extension CGFloat {
    static func random() -> CGFloat {
        return CGFloat(arc4random()) / CGFloat(UInt32.max)
    }
}

extension UIColor {
    static func random() -> UIColor {
        return UIColor(
            red:   .random(),
            green: .random(),
            blue:  .random(),
            alpha: 1.0
        )
    }
}

struct MyCustomData {
    var headline: String = ""
    var support: String = ""
    var blockColors: [UIColor] = [UIColor]()
}

class MPCCell: UITableViewCell {

    @IBOutlet var headlineLabel: UILabel!
    @IBOutlet var supportLabel: UILabel!
    @IBOutlet var vertStackView: UIStackView!

    override func prepareForReuse() {
        super.prepareForReuse()
        // clear previously added subviews from the stack view
        vertStackView.arrangedSubviews.forEach {
            $0.removeFromSuperview()
        }
    }

    func addBlocks(_ colors: [UIColor]) -> Void {

        // for each colr
        colors.forEach {
            // create a view
            let v = UIView()
            // set its background
            v.backgroundColor = $0
            // give view a height constraint, but set its
            //  priority to 999 (prevents auto-layout warnings)
            let c = v.heightAnchor.constraint(equalToConstant: 80.0)
            c.priority = UILayoutPriority(rawValue: 999)
            c.isActive = true
            // add it to the stack view
            vertStackView.addArrangedSubview(v)
        }

    }

}

class ExampleTableViewController: UITableViewController {

    var myData: [MyCustomData] = [MyCustomData]()

    override func viewDidLoad() {
        super.viewDidLoad()

        // lets just create a sample data set
        // 15 rows, with varying number of random-color "blocks"
        // to add to the cell's stack view

        let numBlocks: [Int] = [2, 3, 2, 5, 4]

        for i in 0..<15 {
            var d = MyCustomData()
            d.headline = "Headline \(i + 1)"
            d.support = "Supporting content \(i + 1)"
            if i % 3 == 1 {
                d.support += " - every third row will have more text here, so we can demonstrate auto-height when word wrapping."
            }
            var colors: [UIColor] = [UIColor]()
            for _ in 0..<numBlocks[i % numBlocks.count] {
                colors.append(.random())
            }
            d.blockColors = colors
            myData.append(d)
        }

        let nib = UINib(nibName: "MPCCell", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "MPCCell")

    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myData.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MPCCell", for: indexPath) as! MPCCell

        let d = myData[indexPath.row]

        cell.headlineLabel.text = d.headline
        cell.supportLabel.text = d.support
        cell.addBlocks(d.blockColors)

        return cell
    }

}

答案 1 :(得分:1)

要自动调整tableview单元格的高度,您必须使用自动约束

let box1 = UIView()
box1.translatesAutoresizingMaskIntoConstraints = false
box1.heightAnchor.constraint(equalToConstant: 400).isActive = true
box1.backgroundColor = .yellow
let box2 = UIView()
box2.translatesAutoresizingMaskIntoConstraints = false
box2.heightAnchor.constraint(equalToConstant: 400).isActive = true

box2.backgroundColor = .yellow
cell.verticalStackView.addArrangedSubview(box1)
cell.verticalStackView.addArrangedSubview(box2)

cell.layoutIfNeeded()