5
votes

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. However, that will only be determined when the view is loaded and the content is filled in via viewDidLoad.

enter image description here

So right now I have the view's bottom layout based on the grey text ("S"). In most cases in the app, the grey text will be long enough to wrap multiple lines and then the view height is fine. However, in this case, the image has a bigger height than the text. Is there any way in interface builder to set the autolayout constraint to be relative to the bigger of the two (actually, to be more accurate, relative to the element with the largest maxY frame position)?

2

2 Answers

2
votes

Try this:

enter image description here

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" width="320" height="320"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Pbb-AR-WNn">
                    <rect key="frame" x="20" y="87" width="280" height="147"/>
                    <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" width="64" height="64"/>
                        </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" width="176" height="115"/>
                            <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" width="64" height="64"/>
    </resources>
</document>

The constraints are constructed like:

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

and

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

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

Rintaro's answer was very detailed and helpful, but it wasn't working for me exactly how I wanted. It would work as far as keeping the view a certain minimum height, but it was also cutting off the label at a static height. What I ended up doing was just use the two >= bottom space to container constraints and ommitting the two = ones. This worked great.

enter image description here

enter image description here