3

I have a tableview cell that contains a UIStackView. The stack view contains two labels that could be multiple lines and another stackview at the bottom. This is how the cell should appear, but with more margin. This has a 15 point constraint on the top and bottom on the profile pic ImageView to the superview. Ideally, the 15pt top and bottom constraint would be on the stack view.

enter image description here

When I add the top and bottom constraints from the stack view to the superview, the middle multi-line label is forced to 1 line.

enter image description here

I would like the top and bottom margin with all labels to properly show multiple lines.

If I set the bottom label's vertical resistance higher than the top label, the the top label disappears.

If I set the Vertical Content Hugging Priority to one Label, the other Label gets clipped. If I set both labels Hugging Priority to be equal, the constraints aren't satisfied, and it asks me to make one higher.

I don't understand the logic, I want both labels to grow in height based on the content and size the cell accordingly. Why would I need to give one a Priority?

If I remove the top and bottom constraints from the stack view to the cell's content view, then don't have to set one label's Content Hugging priority higher than the other. But I want the top and bottom constraints for margin.

I tried constraining the labels to the stack views, but it produced the same results. The stack view Alignment is set to Fill. Distribution is set to Fill Proportionally. Changing these values did not change much. The tableview is estimated row height and row height is set to automatic dimension.

Any suggestions?

jscs
  • 63,694
  • 13
  • 151
  • 195
yamski
  • 471
  • 4
  • 14

1 Answers1

3

Give both your image view and stack view:

  • Top and Bottom constraints of >=15
  • CenterY constraint

You cell height will become the greater of the two, and the other one will remain centered vertically.

Here is an example:

enter image description here

and the result:

enter image description here

Note: you will also need to adjust Content Hugging and Compression Resistance Priorities for some of the elements (as is common when using stack views).

Here are the cell and view controller classes I used (obviously, I only set up the elements needed to demonstrate this):

class StackedCell: UITableViewCell {

    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var descriptionLabel: UILabel!

}

class StackCellTableViewController: UITableViewController {

    var theData : [[String]] = [
        ["John Bradford", "This is short text."],
        ["Tom Bradford", "This is long enough text to cause wrapping."],
        ["Fred Bradford", "This text is also long enough to wrap, but this time onto a couple lines -- which will be no problem."],
        ["Mr. David With a Wrapping Name Bradford", "This is short text"],
        ["Mr. Edward With a Wrapping Name Bradford", "Both labels should have enough text to cause wrapping."],
        ]

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

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

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

        cell.titleLabel.text = theData[indexPath.row][0]
        cell.descriptionLabel.text = theData[indexPath.row][1]

        return cell
    }

}

and here is the source for the Storyboard to help get you on your way:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="MSE-mh-zOH">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Stack Cell Table View Controller-->
        <scene sceneID="diu-E1-9Ab">
            <objects>
                <tableViewController id="mgB-HM-TNh" customClass="StackCellTableViewController" customModule="XC10SWScratch" customModuleProvider="target" sceneMemberID="viewController">
                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="NLY-of-j1O">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                        <prototypes>
                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="StackedCell" rowHeight="137" id="8QS-VE-jU8" customClass="StackedCell" customModule="XC10SWScratch" customModuleProvider="target">
                                <rect key="frame" x="0.0" y="28" width="375" height="137"/>
                                <autoresizingMask key="autoresizingMask"/>
                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="8QS-VE-jU8" id="Sks-7v-DrQ">
                                    <rect key="frame" x="0.0" y="0.0" width="375" height="136.5"/>
                                    <autoresizingMask key="autoresizingMask"/>
                                    <subviews>
                                        <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="e9C-Vu-DFw" userLabel="ProfileImage">
                                            <rect key="frame" x="16" y="38.5" width="60" height="60"/>
                                            <color key="backgroundColor" red="0.46202266219999999" green="0.83828371759999998" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                            <constraints>
                                                <constraint firstAttribute="width" secondItem="e9C-Vu-DFw" secondAttribute="height" multiplier="1:1" id="6dF-Hg-kn8"/>
                                                <constraint firstAttribute="width" constant="60" id="cAO-Ur-Qay"/>
                                            </constraints>
                                        </imageView>
                                        <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="lS6-6c-Vgn" userLabel="LabelsStack">
                                            <rect key="frame" x="88" y="36.5" width="226" height="63.5"/>
                                            <subviews>
                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" text="John Bradford" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bi0-SV-Oba">
                                                    <rect key="frame" x="0.0" y="0.0" width="226" height="21.5"/>
                                                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
                                                    <nil key="textColor"/>
                                                    <nil key="highlightedColor"/>
                                                </label>
                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" text="This is the Description Label." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VrD-Zq-XEM">
                                                    <rect key="frame" x="0.0" y="25.5" width="226" height="17"/>
                                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                    <nil key="textColor"/>
                                                    <nil key="highlightedColor"/>
                                                </label>
                                                <view contentMode="scaleToFill" verticalHuggingPriority="1000" translatesAutoresizingMaskIntoConstraints="NO" id="TVE-Sc-9ZR" userLabel="StarsView">
                                                    <rect key="frame" x="0.0" y="46.5" width="226" height="17"/>
                                                    <subviews>
                                                        <stackView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Bxs-Tn-foO" userLabel="StarsStack">
                                                            <rect key="frame" x="0.0" y="0.0" width="148" height="17"/>
                                                            <subviews>
                                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="★" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nvJ-Q5-WhG">
                                                                    <rect key="frame" x="0.0" y="0.0" width="16" height="17"/>
                                                                    <fontDescription key="fontDescription" type="system" pointSize="18"/>
                                                                    <color key="textColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                                    <nil key="highlightedColor"/>
                                                                </label>
                                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="★" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QzW-RR-1Er">
                                                                    <rect key="frame" x="24" y="0.0" width="16" height="17"/>
                                                                    <fontDescription key="fontDescription" type="system" pointSize="18"/>
                                                                    <color key="textColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                                    <nil key="highlightedColor"/>
                                                                </label>
                                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="★" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3HC-Vh-iSJ">
                                                                    <rect key="frame" x="48" y="0.0" width="16" height="17"/>
                                                                    <fontDescription key="fontDescription" type="system" pointSize="18"/>
                                                                    <color key="textColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                                    <nil key="highlightedColor"/>
                                                                </label>
                                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="★" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KC3-u8-XWI">
                                                                    <rect key="frame" x="72" y="0.0" width="16" height="17"/>
                                                                    <fontDescription key="fontDescription" type="system" pointSize="18"/>
                                                                    <color key="textColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                                    <nil key="highlightedColor"/>
                                                                </label>
                                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="★" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="m51-4b-ADh">
                                                                    <rect key="frame" x="96" y="0.0" width="16" height="17"/>
                                                                    <fontDescription key="fontDescription" type="system" pointSize="18"/>
                                                                    <color key="textColor" red="0.75406885150000003" green="0.75408679249999999" blue="0.75407713649999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                                    <nil key="highlightedColor"/>
                                                                </label>
                                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="(53)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aJw-Yl-uQh">
                                                                    <rect key="frame" x="120" y="0.0" width="28" height="17"/>
                                                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                                    <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                                    <nil key="highlightedColor"/>
                                                                </label>
                                                            </subviews>
                                                        </stackView>
                                                    </subviews>
                                                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                                    <constraints>
                                                        <constraint firstItem="Bxs-Tn-foO" firstAttribute="top" secondItem="TVE-Sc-9ZR" secondAttribute="top" id="1C6-g6-TFj"/>
                                                        <constraint firstAttribute="bottom" secondItem="Bxs-Tn-foO" secondAttribute="bottom" id="A5M-bL-fmw"/>
                                                        <constraint firstItem="Bxs-Tn-foO" firstAttribute="leading" secondItem="TVE-Sc-9ZR" secondAttribute="leading" id="gBy-fg-xaP"/>
                                                    </constraints>
                                                </view>
                                            </subviews>
                                        </stackView>
                                        <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="22x-DH-zgf" userLabel="EditButton">
                                            <rect key="frame" x="326" y="53.5" width="33" height="30"/>
                                            <state key="normal" title="EDIT"/>
                                        </button>
                                    </subviews>
                                    <constraints>
                                        <constraint firstAttribute="bottomMargin" relation="greaterThanOrEqual" secondItem="22x-DH-zgf" secondAttribute="bottom" constant="15" id="6ko-9c-f8E"/>
                                        <constraint firstAttribute="bottomMargin" relation="greaterThanOrEqual" secondItem="e9C-Vu-DFw" secondAttribute="bottom" constant="15" id="E8y-Nx-e6k"/>
                                        <constraint firstItem="e9C-Vu-DFw" firstAttribute="centerY" secondItem="Sks-7v-DrQ" secondAttribute="centerY" id="Fsi-Ia-Vh7"/>
                                        <constraint firstItem="22x-DH-zgf" firstAttribute="leading" secondItem="lS6-6c-Vgn" secondAttribute="trailing" constant="12" id="I1T-WO-RhK"/>
                                        <constraint firstItem="22x-DH-zgf" firstAttribute="top" relation="greaterThanOrEqual" secondItem="Sks-7v-DrQ" secondAttribute="topMargin" constant="15" id="Oqf-MF-AyE"/>
                                        <constraint firstItem="lS6-6c-Vgn" firstAttribute="leading" secondItem="e9C-Vu-DFw" secondAttribute="trailing" constant="12" id="Y46-0s-kcr"/>
                                        <constraint firstAttribute="trailingMargin" secondItem="22x-DH-zgf" secondAttribute="trailing" id="c67-Xj-1i7"/>
                                        <constraint firstItem="lS6-6c-Vgn" firstAttribute="top" relation="greaterThanOrEqual" secondItem="Sks-7v-DrQ" secondAttribute="top" constant="15" id="ei6-pz-Bnr"/>
                                        <constraint firstItem="lS6-6c-Vgn" firstAttribute="centerY" secondItem="Sks-7v-DrQ" secondAttribute="centerY" id="mys-LE-jkm"/>
                                        <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="lS6-6c-Vgn" secondAttribute="bottom" constant="15" id="rHM-XF-n4C"/>
                                        <constraint firstItem="e9C-Vu-DFw" firstAttribute="leading" secondItem="Sks-7v-DrQ" secondAttribute="leadingMargin" id="uP4-26-6Uc"/>
                                        <constraint firstItem="e9C-Vu-DFw" firstAttribute="top" relation="greaterThanOrEqual" secondItem="Sks-7v-DrQ" secondAttribute="topMargin" constant="15" id="x1z-ox-koN"/>
                                        <constraint firstItem="22x-DH-zgf" firstAttribute="centerY" secondItem="Sks-7v-DrQ" secondAttribute="centerY" id="zxj-IG-DbW"/>
                                    </constraints>
                                </tableViewCellContentView>
                                <connections>
                                    <outlet property="descriptionLabel" destination="VrD-Zq-XEM" id="YT1-t7-FtK"/>
                                    <outlet property="titleLabel" destination="bi0-SV-Oba" id="wu2-Ty-yge"/>
                                </connections>
                            </tableViewCell>
                        </prototypes>
                        <connections>
                            <outlet property="dataSource" destination="mgB-HM-TNh" id="Fsm-c0-afH"/>
                            <outlet property="delegate" destination="mgB-HM-TNh" id="Uht-Ga-aoa"/>
                        </connections>
                    </tableView>
                    <navigationItem key="navigationItem" id="VCY-uQ-EQ7"/>
                </tableViewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="uPF-XE-23l" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="924" y="737.18140929535241"/>
        </scene>
        <!--Navigation Controller-->
        <scene sceneID="F8k-zt-Ijc">
            <objects>
                <navigationController automaticallyAdjustsScrollViewInsets="NO" id="MSE-mh-zOH" sceneMemberID="viewController">
                    <toolbarItems/>
                    <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="9T6-F6-vim">
                        <rect key="frame" x="0.0" y="20" width="375" height="44"/>
                        <autoresizingMask key="autoresizingMask"/>
                    </navigationBar>
                    <nil name="viewControllers"/>
                    <connections>
                        <segue destination="mgB-HM-TNh" kind="relationship" relationship="rootViewController" id="Dpn-ba-QhM"/>
                    </connections>
                </navigationController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="zHK-UX-1Sq" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="-15.199999999999999" y="737.18140929535241"/>
        </scene>
    </scenes>
</document>
DonMag
  • 69,424
  • 5
  • 50
  • 86