自定义 UITableViewCell 的自动布局在 Swift 5 中发现冲突约束

Autolayout of custom UITableViewCell finds conflicting constraints in Swift 5

我遇到了以下问题。我正在使用 Autolayout 设计一个自定义的 UITableViewCell Design,一切都完美无缺。 Xcode 没有显示任何错误。

但是当我在模拟器或实际 iPhone 上执行 运行 应用程序时,我在控制台中收到以下错误代码:

2020-04-16 17:14:36.928201+0200 Promille[11911:1025126] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600000ddc460 UIStackView:0x7f8bba72bb20.height == 75   (active)>",
    "<NSLayoutConstraint:0x600000ddc7d0 V:[UIStackView:0x7f8bba72bb20]-(10)-|   (active, names: '|':UITableViewCellContentView:0x7f8bba712390 )>",
    "<NSLayoutConstraint:0x600000ddc870 V:|-(10)-[UIStackView:0x7f8bba72bb20]   (active, names: '|':UITableViewCellContentView:0x7f8bba712390 )>",
    "<NSLayoutConstraint:0x600000dde0d0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f8bba712390.height == 95.5   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600000ddc460 UIStackView:0x7f8bba72bb20.height == 75   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

错误与高度有关,因为只要我删除高度限制,一切都会完美。但是在这种情况下,两张图片都是全尺寸的,并且 TableViewCell 的高度超过 1000 像素。

这里还有一张 .xib 文件的图片:

真正奇怪的是我在运行的时候没有改变任何约束。仅更改文本标签。那么怎么会是自动布局发现错误,设计布局时自动布局没有发现呢?


你知道错误消息中的最后一个约束是关于什么的吗,因为我没有设置内容视图的高度。

<NSLayoutConstraint:0x600000dde0d0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x7f8bba712390.height == 95.5   (active)>"

希望大家能想出出现这个问题的原因/解决方法

您可以像这样 对情节提要中的单元格进行约束。

然后就可以在这个方法中设置tableviewcell的高度了

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 75
}

那你就不需要在storyboard中设置cell的高度了。您也可以在这里使用动态高度,例如,使其成为整个屏幕尺寸的一半。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return self.view.bounds.height / 0.5
}

要添加此方法,您需要符合

extension ViewController: UITableViewDelegate, UITableViewDataSource 

您不需要 tableviewdelegate,但为其他 tableviewmethods 添加它。不要忘记设置委托

tableview.delegate = self

这似乎是一个普遍的问题。

虽然约束可能是正确的,但自动布局会在调整单元格高度时生成该警告。

将堆栈视图的高度限制的优先级更改为 999 应该可以解决问题。


编辑

这是一个示例 - 布局应该接近您所显示的内容。

我给每个图像视图设置了 30 的宽度和 1:1 比例。

我给 "Outer" 堆栈视图设置了 75 的高度限制,但请注意,我没有将其优先级设置为 999,而是将其底部限制设置为 大于或等于 到 8。这也消除了 运行 时间布局问题,还让我可以进行单元格设计,而不必担心 Interface Builder 抱怨单元格高度。

因此,在 运行 时,实际单元格高度将为 75 加上 8 磅顶部和底部 "padding."

这是 运行 时间的样子:

这是我使用的代码:

class RegistrationCell: UITableViewCell {

    @IBOutlet var lblName: UILabel!
    @IBOutlet var lblAge: UILabel!
    @IBOutlet var lblGender: UILabel!
    @IBOutlet var lblWeight: UILabel!

}

struct Benutzer {
    var name: String = ""
    var age: Int = 0
    var gender: Int = 0
    var weight: Float = 0.0
}

class RegistrationTableViewController: UITableViewController {

    var myData: [Benutzer] = [
        Benutzer(name: "Christian", age: 24, gender: 0, weight: 81.0),
        Benutzer(name: "Tobias", age: 25, gender: 0, weight: 83.5),
        Benutzer(name: "Astrid", age: 22, gender: 1, weight: 50.0),
        Benutzer(name: "Frank", age: 26, gender: 0, weight: 82.0),
        Benutzer(name: "Birgit", age: 21, gender: 1, weight: 49.5),
        Benutzer(name: "Petra", age: 23, gender: 1, weight: 48.0),
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.register(UINib(nibName: "RegistrationCell", bundle: nil), forCellReuseIdentifier: "Cell")

    }

    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: "Cell", for: indexPath) as! RegistrationCell

        let d = myData[indexPath.row]
        cell.lblName.text = d.name
        cell.lblAge.text = "\(d.age)"
        cell.lblGender.text = d.gender == 0 ? "M" : "F"
        cell.lblWeight.text = "\(d.weight)"

        return cell
    }

}

这是我的 RegistrationCell.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="123" id="7Ao-kn-tXV" customClass="RegistrationCell" customModule="MiniScratch" customModuleProvider="target">
            <rect key="frame" x="0.0" y="0.0" width="414" height="123"/>
            <autoresizingMask key="autoresizingMask"/>
            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="7Ao-kn-tXV" id="47R-qN-jmt">
                <rect key="frame" x="0.0" y="0.0" width="414" height="123"/>
                <autoresizingMask key="autoresizingMask"/>
                <subviews>
                    <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="w3y-Sd-Nos" userLabel="OuterStack">
                        <rect key="frame" x="8" y="8" width="398" height="75"/>
                        <subviews>
                            <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="wyp-v1-tmD" userLabel="NameStack">
                                <rect key="frame" x="0.0" y="0.0" width="398" height="37.5"/>
                                <subviews>
                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="person" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="Fjj-yM-fPo" userLabel="img Profile Image">
                                        <rect key="frame" x="0.0" y="5.5" width="30" height="27.5"/>
                                        <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        <constraints>
                                            <constraint firstAttribute="width" constant="30" id="GMk-hN-m2Y"/>
                                            <constraint firstAttribute="width" secondItem="Fjj-yM-fPo" secondAttribute="height" multiplier="1:1" id="twh-eK-7fi"/>
                                        </constraints>
                                    </imageView>
                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Neuer Benutzer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7L6-cN-3lF">
                                        <rect key="frame" x="42" y="5.5" width="314" height="26.5"/>
                                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
                                        <nil key="textColor"/>
                                        <nil key="highlightedColor"/>
                                    </label>
                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="checkmark.seal.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="2LH-yE-mwq" userLabel="img Active">
                                        <rect key="frame" x="368" y="3.5" width="30" height="31.5"/>
                                        <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        <constraints>
                                            <constraint firstAttribute="width" constant="30" id="Ar9-oX-QRg"/>
                                            <constraint firstAttribute="width" secondItem="2LH-yE-mwq" secondAttribute="height" multiplier="1:1" id="iIC-xx-qUj"/>
                                        </constraints>
                                    </imageView>
                                </subviews>
                            </stackView>
                            <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="23" translatesAutoresizingMaskIntoConstraints="NO" id="moe-fr-waY" userLabel="LowerStack">
                                <rect key="frame" x="0.0" y="37.5" width="398" height="37.5"/>
                                <subviews>
                                    <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="p9M-2u-yIn" userLabel="AgeStack">
                                        <rect key="frame" x="0.0" y="0.0" width="117.5" height="37.5"/>
                                        <subviews>
                                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="calendar" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="JLv-Bq-0aO">
                                                <rect key="frame" x="0.0" y="5" width="30" height="27.5"/>
                                                <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                <constraints>
                                                    <constraint firstAttribute="width" constant="30" id="329-R5-jp7"/>
                                                    <constraint firstAttribute="width" secondItem="JLv-Bq-0aO" secondAttribute="height" multiplier="1:1" id="FCZ-nk-tMN"/>
                                                </constraints>
                                            </imageView>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WG8-WN-s2X">
                                                <rect key="frame" x="42" y="8.5" width="75.5" height="20.5"/>
                                                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                        </subviews>
                                    </stackView>
                                    <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="tfc-eV-c24" userLabel="GenderStack">
                                        <rect key="frame" x="140.5" y="0.0" width="117" height="37.5"/>
                                        <subviews>
                                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="person.2.square.stack.fill" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="VQ9-tf-mkF">
                                                <rect key="frame" x="0.0" y="3" width="30" height="31.5"/>
                                                <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                <constraints>
                                                    <constraint firstAttribute="width" constant="30" id="1xw-b0-vZp"/>
                                                    <constraint firstAttribute="width" secondItem="VQ9-tf-mkF" secondAttribute="height" multiplier="1:1" id="zmL-Jl-F55"/>
                                                </constraints>
                                            </imageView>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tg8-Bx-TWD">
                                                <rect key="frame" x="42" y="8.5" width="75" height="20.5"/>
                                                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                        </subviews>
                                    </stackView>
                                    <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="9bU-4J-00h" userLabel="WeightStack">
                                        <rect key="frame" x="280.5" y="0.0" width="117.5" height="37.5"/>
                                        <subviews>
                                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="gauge" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="uXN-UL-NhM">
                                                <rect key="frame" x="0.0" y="4.5" width="30" height="29"/>
                                                <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                <constraints>
                                                    <constraint firstAttribute="width" constant="30" id="3dU-2L-zOp"/>
                                                    <constraint firstAttribute="width" secondItem="uXN-UL-NhM" secondAttribute="height" multiplier="1:1" id="xI1-Qm-Vr5"/>
                                                </constraints>
                                            </imageView>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wwy-kf-N2Z">
                                                <rect key="frame" x="42" y="8.5" width="75.5" height="20.5"/>
                                                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                        </subviews>
                                    </stackView>
                                </subviews>
                            </stackView>
                        </subviews>
                        <constraints>
                            <constraint firstAttribute="height" constant="75" id="jPs-ix-1GZ"/>
                        </constraints>
                    </stackView>
                </subviews>
                <color key="backgroundColor" red="0.99996358159999998" green="0.77101260419999995" blue="0.16773471240000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                <constraints>
                    <constraint firstItem="w3y-Sd-Nos" firstAttribute="leading" secondItem="47R-qN-jmt" secondAttribute="leading" constant="8" id="ba9-oa-K7s"/>
                    <constraint firstItem="w3y-Sd-Nos" firstAttribute="top" secondItem="47R-qN-jmt" secondAttribute="top" constant="8" id="hO0-zC-Vbj"/>
                    <constraint firstAttribute="trailing" secondItem="w3y-Sd-Nos" secondAttribute="trailing" constant="8" id="s1f-TA-lYa"/>
                    <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="w3y-Sd-Nos" secondAttribute="bottom" constant="8" id="ypb-vP-adn"/>
                </constraints>
            </tableViewCellContentView>
            <connections>
                <outlet property="lblAge" destination="WG8-WN-s2X" id="WBO-bZ-8SE"/>
                <outlet property="lblGender" destination="tg8-Bx-TWD" id="bTQ-bI-zSz"/>
                <outlet property="lblName" destination="7L6-cN-3lF" id="scr-s2-IiF"/>
                <outlet property="lblWeight" destination="Wwy-kf-N2Z" id="3pY-yL-8Ys"/>
            </connections>
            <point key="canvasLocation" x="-252.17391304347828" y="53.236607142857139"/>
        </tableViewCell>
    </objects>
    <resources>
        <image name="calendar" catalog="system" width="64" height="52"/>
        <image name="checkmark.seal.fill" catalog="system" width="64" height="60"/>
        <image name="gauge" catalog="system" width="64" height="60"/>
        <image name="person" catalog="system" width="64" height="58"/>
        <image name="person.2.square.stack.fill" catalog="system" width="56" height="64"/>
    </resources>
</document>