iOS Autolayout 视图高度基于较大的子视图高度

Posted

技术标签:

【中文标题】iOS Autolayout 视图高度基于较大的子视图高度【英文标题】:iOS Autolayout view height based on larger subview height 【发布时间】:2015-05-27 05:42:32 【问题描述】:

所以我在界面生成器中有一个视图,我希望它的高度基于其中两个子视图中较大的(高度)。但是,只有在加载视图并通过 viewDidLoad 填充内容时才能确定。

所以现在我有了基于灰色文本(“S”)的视图底部布局。在应用程序中的大多数情况下,灰色文本将足够长以换行多行,然后视图高度就可以了。但是,在这种情况下,图像的高度大于文本。界面生成器中是否有任何方法可以将自动布局约束设置为相对于两者中的较大者(实际上,更准确地说,相对于具有最大 maxY 帧位置的元素)?

【问题讨论】:

【参考方案1】:

试试这个:

TestView.xib

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="ios.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view contentMode="scaleToFill" id="iN0-l3-epB">
            <rect key="frame" x="0.0" y="0.0"  />
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Pbb-AR-WNn">
                    <rect key="frame" x="20" y="87"  />
                    <subviews>
                        <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" image="dragon" translatesAutoresizingMaskIntoConstraints="NO" id="D5g-gu-1ev">
                            <rect key="frame" x="16" y="16"  />
                        </imageView>
                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5iM-Zb-gNn">
                            <rect key="frame" x="88" y="16"  />
                            <string key="text">So I have a view in interface builder and I want its height to be based on the larger (height-wise) of the two subviews inside of it.</string>
                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
                            <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                            <nil key="highlightedColor"/>
                        </label>
                    </subviews>
                    <color key="backgroundColor" white="0.90000000000000002" alpha="1" colorSpace="calibratedWhite"/>
                    <constraints>
                        <constraint firstAttribute="width" constant="280" id="2xn-1g-Vuq"/>
                        <constraint firstAttribute="bottom" secondItem="D5g-gu-1ev" secondAttribute="bottom" priority="750" constant="16" id="6rO-0a-xvp"/>
                        <constraint firstAttribute="bottom" secondItem="5iM-Zb-gNn" secondAttribute="bottom" priority="750" constant="16" id="B4u-tf-NJf"/>
                        <constraint firstItem="D5g-gu-1ev" firstAttribute="leading" secondItem="Pbb-AR-WNn" secondAttribute="leading" constant="16" id="GZ7-e9-kF0"/>
                        <constraint firstItem="D5g-gu-1ev" firstAttribute="top" secondItem="Pbb-AR-WNn" secondAttribute="top" constant="16" id="K8m-xD-EsT"/>
                        <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="D5g-gu-1ev" secondAttribute="bottom" constant="16" id="KEK-Q2-z4j"/>
                        <constraint firstItem="5iM-Zb-gNn" firstAttribute="leading" secondItem="D5g-gu-1ev" secondAttribute="trailing" constant="8" id="QLz-Q2-13S"/>
                        <constraint firstItem="5iM-Zb-gNn" firstAttribute="top" secondItem="Pbb-AR-WNn" secondAttribute="top" constant="16" id="bpN-WA-APq"/>
                        <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="5iM-Zb-gNn" secondAttribute="bottom" constant="16" id="dbe-Qg-fJU"/>
                        <constraint firstAttribute="trailing" secondItem="5iM-Zb-gNn" secondAttribute="trailing" constant="16" id="yIE-Eq-dw0"/>
                    </constraints>
                </view>
            </subviews>
            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
            <constraints>
                <constraint firstAttribute="centerY" secondItem="Pbb-AR-WNn" secondAttribute="centerY" id="Ts3-XA-WC0"/>
                <constraint firstAttribute="centerX" secondItem="Pbb-AR-WNn" secondAttribute="centerX" id="uS3-QD-gfi"/>
            </constraints>
            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
            <point key="canvasLocation" x="365" y="328"/>
        </view>
    </objects>
    <resources>
        <image name="dragon"  />
    </resources>
</document>

约束的构造如下:

H:[panel(280)]
H:|-16-[imageView]-8-[labelView]-16-|
V:|-16-[imageView]-(16@750,>=16)-|
V:|-16-[labelView]-(16@750,>=16)-|

imageView.contentHuggingPriorityForAxis(.Vertical) == 1000
imageView.contentCompressionResistancePriorityForAxis(.Vertical) == 1000

labelView.contentHuggingPriorityForAxis(.Vertical) == 1000
labelView.contentCompressionResistancePriorityForAxis(.Vertical) == 1000

【讨论】:

谢谢林太郎。原来我什至不需要有 4 个底部约束。我所需要的只是将两个子视图的底部布局设置为容器约束 >= X,并完全省略 = X 布局。【参考方案2】:

Rintaro 的回答非常详细且很有帮助,但它并不完全符合我的要求。它可以将视图保持在某个最小高度,但它也会在静态高度处切断标签。我最终做的只是将两个 >= 底部空间用于容器约束并省略两个 = 。这效果很好。

【讨论】:

以上是关于iOS Autolayout 视图高度基于较大的子视图高度的主要内容,如果未能解决你的问题,请参考以下文章

iOS AutoLayout 自动调整整个表格(不是单元格!)高度

iOS将autoLayout按钮位置设置为故事板中心的剩余空间

iOS:UIView 的 Autolayout 拉伸高度过多(Xcode 8、Swift 3)

IOS - UIView中使用AutoLayout的UILabel动态高度

没有 Interface Builder 的 UIScrollView 和 Autolayout - 滚动视图如何获得它的高度?

iOS Update Interface Builder视图框架基于约束