UITableView scroll outside of frame - swift

I have a UITableView with a fixed width. The table is centered in its container so that there are white margins both on the left and the right.
Is it possible to scroll the table also with the finger on the white space?
Thanks in advance!
EDIT: after matt suggestion i've tried with a pan gesture recognizer
unfortunately it's not working so smooth, there is no bounce at all
#IBAction func handlePan(recognizer:UIPanGestureRecognizer) {
let translation = recognizer.translation(in: self.view)
self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.contentOffset.y - translation.y), animated: true)
}

You can put tableview in a scrollview and set Clip to Bounds to false. Shared storyboard sample below.
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina5_5" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="OptionalTest" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zrT-93-180">
<rect key="frame" x="65" y="149" width="221" height="134"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<scrollView multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TPs-fa-Cha">
<rect key="frame" x="20" y="20" width="374" height="429"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LQo-x0-VDn">
<rect key="frame" x="0.0" y="0.0" width="414" height="429"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8PI-hl-lry">
<rect key="frame" x="-20" y="0.0" width="414" height="429"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="2v6-FK-vyt">
<rect key="frame" x="30" y="20" width="354" height="389"/>
<color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="gZa-kH-87J">
<rect key="frame" x="0.0" y="28" width="354" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="gZa-kH-87J" id="Oid-Rc-aH5">
<rect key="frame" x="0.0" y="0.0" width="354" height="43.666666666666664"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Test" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dJP-b6-Ftm">
<rect key="frame" x="20" y="11" width="500" height="22"/>
<constraints>
<constraint firstAttribute="height" priority="750" constant="50" id="vcL-NN-bXq"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="bottomMargin" secondItem="dJP-b6-Ftm" secondAttribute="bottom" id="DgB-3a-RR8"/>
<constraint firstItem="dJP-b6-Ftm" firstAttribute="leading" secondItem="Oid-Rc-aH5" secondAttribute="leadingMargin" id="Hli-JL-2Qr"/>
<constraint firstAttribute="trailingMargin" secondItem="dJP-b6-Ftm" secondAttribute="trailing" id="kia-ek-skG"/>
<constraint firstItem="dJP-b6-Ftm" firstAttribute="top" secondItem="Oid-Rc-aH5" secondAttribute="topMargin" id="l5N-zS-cxF"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
</tableView>
</subviews>
<color key="backgroundColor" red="0.75004076959999999" green="0.1040449888" blue="0.1206566915" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="2v6-FK-vyt" secondAttribute="bottom" constant="20" id="Edy-hU-GY1"/>
<constraint firstAttribute="width" constant="414" id="Isx-E5-2uJ"/>
<constraint firstAttribute="trailing" secondItem="2v6-FK-vyt" secondAttribute="trailing" constant="30" id="OTY-td-pfO"/>
<constraint firstItem="2v6-FK-vyt" firstAttribute="leading" secondItem="8PI-hl-lry" secondAttribute="leading" constant="30" id="T7h-dc-4QT"/>
<constraint firstItem="2v6-FK-vyt" firstAttribute="top" secondItem="8PI-hl-lry" secondAttribute="top" constant="20" id="dcV-5c-pkc"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="8PI-hl-lry" secondAttribute="trailing" constant="20" id="018-wR-9xA"/>
<constraint firstItem="8PI-hl-lry" firstAttribute="leading" secondItem="LQo-x0-VDn" secondAttribute="leading" constant="-20" id="FKC-nR-YRp"/>
<constraint firstItem="8PI-hl-lry" firstAttribute="top" secondItem="LQo-x0-VDn" secondAttribute="top" id="Gqv-OU-P2f"/>
<constraint firstAttribute="bottom" secondItem="8PI-hl-lry" secondAttribute="bottom" id="KK5-wW-ozL"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="LQo-x0-VDn" secondAttribute="trailing" id="AE2-7E-9HG"/>
<constraint firstItem="LQo-x0-VDn" firstAttribute="width" secondItem="TPs-fa-Cha" secondAttribute="width" priority="250" id="Rte-o0-Glp"/>
<constraint firstItem="LQo-x0-VDn" firstAttribute="top" secondItem="TPs-fa-Cha" secondAttribute="top" id="aEU-v5-Cad"/>
<constraint firstAttribute="bottom" secondItem="LQo-x0-VDn" secondAttribute="bottom" id="cO7-2E-0pT"/>
<constraint firstItem="LQo-x0-VDn" firstAttribute="leading" secondItem="TPs-fa-Cha" secondAttribute="leading" id="m81-U4-SNF"/>
<constraint firstItem="LQo-x0-VDn" firstAttribute="height" secondItem="TPs-fa-Cha" secondAttribute="height" id="owm-Yu-tsT"/>
</constraints>
</scrollView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="EJ1-7L-gD8">
<rect key="frame" x="0.0" y="481" width="414" height="255"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9zS-iV-m0P">
<rect key="frame" x="0.0" y="0.0" width="414" height="127.66666666666667"/>
<color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lpS-nX-jsH">
<rect key="frame" x="0.0" y="127.66666666666663" width="414" height="127.33333333333331"/>
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
</view>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="255" id="oGk-Vz-GWg"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="EJ1-7L-gD8" firstAttribute="bottom" secondItem="6Tk-OE-BBY" secondAttribute="bottom" id="EgJ-Wh-ZOP"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="EJ1-7L-gD8" secondAttribute="trailing" id="Srj-nB-74S"/>
<constraint firstItem="TPs-fa-Cha" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="frI-np-m0B"/>
<constraint firstItem="EJ1-7L-gD8" firstAttribute="top" secondItem="TPs-fa-Cha" secondAttribute="bottom" constant="32" id="jfk-9F-7WW"/>
<constraint firstItem="TPs-fa-Cha" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="20" id="pR9-do-d64"/>
<constraint firstItem="TPs-fa-Cha" firstAttribute="trailing" secondItem="6Tk-OE-BBY" secondAttribute="trailing" constant="-20" id="r3d-o9-LYw"/>
<constraint firstItem="EJ1-7L-gD8" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="vmi-E0-e52"/>
</constraints>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
<connections>
<outlet property="label" destination="zrT-93-180" id="9YE-hX-UB7"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="139.13043478260872" y="132.06521739130434"/>
</scene>
</scenes>
</document>

Related

Vertical scroll not work in uiScrollView swift

Try to have scrollview inside stackview
But when i try to scroll it, it's not working. Label is already more than enough to make it scrollable
Is there any missing constarint ?
Main view is in freeform already
Try adding height constraints to the scroll view as it appears that you only have a leading and trailing constraint. You could either try a fixed height size or anchor the top and bottom. Also, your content view should not be anchored to the scroll view. Instead make it have an equal width to the scroll view and then let the height be dictated by the height of the label.
You have some confusing constraints there...
Here is what you want:
and here's the source for that xib, so you can inspect it:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_0" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<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"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KN0-8I-kAw" userLabel="Danakini Round View">
<rect key="frame" x="20" y="109" width="280" height="350"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="MCE-fF-1F3">
<rect key="frame" x="20" y="20" width="240" height="310"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Lorem Ipsum" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pf4-se-Y1l">
<rect key="frame" x="0.0" y="0.0" width="240" height="19.5"/>
<color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gMy-4J-nYd" userLabel="HRline">
<rect key="frame" x="0.0" y="27.5" width="240" height="2"/>
<color key="backgroundColor" systemColor="systemGray4Color"/>
<constraints>
<constraint firstAttribute="height" constant="2" id="6r4-ym-L9o"/>
</constraints>
</view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ohd-cQ-8q4">
<rect key="frame" x="0.0" y="37.5" width="240" height="234.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bgh-GP-EOo" userLabel="contentView">
<rect key="frame" x="0.0" y="0.0" width="240" height="412"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dK0-nd-d8A" userLabel="contentLabel">
<rect key="frame" x="0.0" y="0.0" width="240" height="412"/>
<color key="backgroundColor" red="0.83216959239999999" green="0.98548370600000001" blue="0.47333085539999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<mutableString key="text">There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.</mutableString>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemYellowColor"/>
<constraints>
<constraint firstItem="dK0-nd-d8A" firstAttribute="leading" secondItem="bgh-GP-EOo" secondAttribute="leading" id="VRW-2Y-78C"/>
<constraint firstItem="dK0-nd-d8A" firstAttribute="top" secondItem="bgh-GP-EOo" secondAttribute="top" id="X7H-fn-51f"/>
<constraint firstAttribute="trailing" secondItem="dK0-nd-d8A" secondAttribute="trailing" id="nLX-pf-k0n"/>
<constraint firstAttribute="bottom" secondItem="dK0-nd-d8A" secondAttribute="bottom" id="qNF-7Y-zTJ"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="bgh-GP-EOo" firstAttribute="bottom" secondItem="js6-NC-3lf" secondAttribute="bottom" id="GpI-in-K5y"/>
<constraint firstItem="bgh-GP-EOo" firstAttribute="top" secondItem="js6-NC-3lf" secondAttribute="top" id="NnM-Sv-lEs"/>
<constraint firstItem="bgh-GP-EOo" firstAttribute="width" secondItem="sm0-LU-kFC" secondAttribute="width" id="Ubq-5K-iJW"/>
<constraint firstItem="bgh-GP-EOo" firstAttribute="leading" secondItem="js6-NC-3lf" secondAttribute="leading" id="ijJ-VO-Qpg"/>
<constraint firstItem="bgh-GP-EOo" firstAttribute="trailing" secondItem="js6-NC-3lf" secondAttribute="trailing" id="qln-zf-sri"/>
</constraints>
<viewLayoutGuide key="contentLayoutGuide" id="js6-NC-3lf"/>
<viewLayoutGuide key="frameLayoutGuide" id="sm0-LU-kFC"/>
</scrollView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TdZ-YS-MhG">
<rect key="frame" x="0.0" y="280" width="240" height="30"/>
<color key="backgroundColor" red="0.0" green="0.68455910679999998" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Oke">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="MCE-fF-1F3" secondAttribute="bottom" constant="20" id="0TY-J1-O6O"/>
<constraint firstItem="MCE-fF-1F3" firstAttribute="top" secondItem="KN0-8I-kAw" secondAttribute="top" constant="20" id="3sN-Gw-elq"/>
<constraint firstItem="MCE-fF-1F3" firstAttribute="leading" secondItem="KN0-8I-kAw" secondAttribute="leading" constant="20" id="5yr-mw-wRa"/>
<constraint firstAttribute="trailing" secondItem="MCE-fF-1F3" secondAttribute="trailing" constant="20" id="TQ3-xf-j3R"/>
<constraint firstAttribute="height" constant="350" id="hgx-Uc-HlF"/>
<constraint firstAttribute="width" constant="280" id="mF4-ca-APk"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<color key="backgroundColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="KN0-8I-kAw" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="BJu-bh-5Rp"/>
<constraint firstItem="KN0-8I-kAw" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="ZN8-S1-ftW"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="139" y="153"/>
</view>
</objects>
<resources>
<systemColor name="systemGray4Color">
<color red="0.81960784313725488" green="0.81960784313725488" blue="0.83921568627450982" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemYellowColor">
<color red="1" green="0.80000000000000004" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>

Why Hugging priority is ignored?

I made a text bubble which have 2 dynamic horizontal constraints with superview: left with 1000 priority and right with 100 priority. If bubble was created by user left constraint will have 100 priority and right will have 1000 priority.
Inside of Bubble there is StackView with labels. Stack view is constrained to have the same size as bubble.
Both hugging and compression priorities of labels are higher than 100 and lower than 1000(but upper label have a priority over lower).
Idea is simple, constraint with priority 100 will be broken, and bubble will be as big as it needs to show the whole text.
However it doesn't work. Bubbles are much bigger than they should be. It seems that autolayout ignores hugging priorities.
Here are description of all constraints of the bubble with text "Hhbhj":
<NSLayoutConstraint:0x283341630 V:|-(10)-[UIStackView:0x113310d90] (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x283341810 H:[UIView:0x113310c20]-(>=16)-| (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x2833414a0 UILabel:0x113311360.height >= 14 priority:999 (active)>
<NSLayoutConstraint:0x2833416d0 V:|-(6)-[UIView:0x113310c20] (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283341540 H:|-(10)-[UIStackView:0x113310d90] (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x2833415e0 V:[UIStackView:0x113310d90]-(10)-| (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x283340be0 UIImageView:0x113310f20.width == 0 priority:1 (active)>
<NSLayoutConstraint:0x283341680 H:[UIView:0x113310c20]-(16)-| (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283341360 UILabel:0x1133110f0.height >= 24 priority:999 (active)>
<NSLayoutConstraint:0x2833417c0 H:|-(16#100)-[UIView:0x113310c20] priority:100 (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283341770 H:|-(>=16)-[UIView:0x113310c20] (active, names: '|':UITableViewCellContentView:0x113310a90 )>
<NSLayoutConstraint:0x283340c80 UIImageView:0x113310f20.height == 183 priority:999 (active)>
<NSLayoutConstraint:0x283341590 H:[UIStackView:0x113310d90]-(10)-| (active, names: '|':UIView:0x113310c20 )>
<NSLayoutConstraint:0x283341720 V:[UIView:0x113310c20]-(6)-| (active, names: '|':UITableViewCellContentView:0x113310a90 )>
P.S You can also see an imageView in bubble. Don't worry if there is no image in bubble imageView will be hidden and constraints will be deactivated.
P.S.S Two vertical greater than constraints, just ensure that bubble will not get bigger than they need to be.
Here is one way to approach this...
For your labels, give the top (the message) label:
Content Hugging Priority
Horizontal: 750
Vertical: 1000
Content Compression Resistance Priority
Horizontal: 1000
Vertical: 750
and give the bottom (the time) label:
Content Hugging Priority
Horizontal: 251
Vertical: 1000
Content Compression Resistance Priority
Horizontal: 1000
Vertical: 750
There are two examples here... the top one will constrain the "bubble view" to the cell's Content View margins. The bottom one will constrain the width of the "bubble view" to 80% of the width of the cell.
Setup your constraints like this - ALL with Priority: 1000:
define #IBOutlet vars for the leading and trailing constraints:
#IBOutlet var sentConstraint: NSLayoutConstraint!
#IBOutlet var receivedConstraint: NSLayoutConstraint!
connect sentConstraint to the Bubble View.trailing = trailingMargin constraint, and connect receivedConstraint to the Bubble View.leading = leadingMargin constraint.
It will now look like this:
When you set the data for the cell, activate / deactivate the corresponding constraint, for example:
// activate / deactivate Trailing / Leading constraints
// based on sent or received
sentConstraint.isActive = msg.type == .sent
receivedConstraint.isActive = msg.type == .received
The >= Leading and Trailing constraints will prevent the bubble view from extending outside the content view frame.
Here's how it could look:
It's common in messaging apps to leave a bit of "padding" on the side. By limiting the width of the bubble view to 80%, it could look like this:
Here's the code I used to produce this layout:
enum MessageType {
case sent, received
}
struct MessageStruct {
var imageName: String = ""
var message: String = ""
var time: String = ""
var type: MessageType = .sent
}
class BubbleCell: UITableViewCell {
#IBOutlet var bubbleView: UIView!
#IBOutlet var myImageView: UIImageView!
#IBOutlet var messageLabel: UILabel!
#IBOutlet var timeLabel: UILabel!
#IBOutlet var sentConstraint: NSLayoutConstraint!
#IBOutlet var receivedConstraint: NSLayoutConstraint!
func fillData(_ msg: MessageStruct) -> Void {
// I don't know how you're getting / setting your possible image,
// so I'll just set it to hidden for now
myImageView.isHidden = true
// set message label text
messageLabel.text = msg.message
// set time label text, append either sent or rec'd
// and set alignment
timeLabel.text = msg.time + (msg.type == .sent ? " - sent" : " - rec'd")
timeLabel.textAlignment = msg.type == .sent ? .right : .left
// set colors based on sent or received
bubbleView.backgroundColor = msg.type == .sent ? .systemGreen : .white
messageLabel.textColor = msg.type == .sent ? .white : .black
timeLabel.textColor = msg.type == .sent ? .white : .black
// activate / deactivate Trailing / Leading constraints
// based on sent or received
sentConstraint.isActive = msg.type == .sent
receivedConstraint.isActive = msg.type == .received
// set corner radii based on sent or received
bubbleView.layer.cornerRadius = 16
bubbleView.layer.maskedCorners = msg.type == .sent
? [.layerMaxXMinYCorner, .layerMinXMinYCorner, .layerMinXMaxYCorner]
: [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMinYCorner]
}
}
class MessageTableViewController: UITableViewController {
var myData: [MessageStruct] = []
override func viewDidLoad() {
super.viewDidLoad()
var msg: MessageStruct!
msg = MessageStruct(imageName: "",
message: "Short message.",
time: "09:15",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Short message.",
time: "09:15",
type: .received)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "This is a longer message.",
time: "09:20",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "This is a longer message.",
time: "09:20",
type: .received)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "This message should be long enough that it needs to wrap in the cell.",
time: "09:25",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Another Short message.",
time: "09:30",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Another message, long enough that it will need to wrap in the cell.",
time: "09:35",
type: .sent)
myData.append(msg)
msg = MessageStruct(imageName: "",
message: "Another message, long enough that it will need to wrap in the cell.",
time: "09:35",
type: .received)
myData.append(msg)
tableView.separatorStyle = .none
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// use "bubbleCell" identifier for margin-width limit
// use "bubble80Cell" identifier for 80% width limit
let c = tableView.dequeueReusableCell(withIdentifier: "bubbleCell", for: indexPath) as! BubbleCell
let d = myData[indexPath.row]
c.fillData(d)
return c
}
}
and here's the Storyboard source so you can inspect it:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="t48-nh-14V">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Message Table View Controller-->
<scene sceneID="mMr-vR-h6X">
<objects>
<tableViewController id="t48-nh-14V" customClass="MessageTableViewController" customModule="QuickTest" 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="BrW-mC-6e6">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="bubbleCell" rowHeight="260" id="Oi2-T7-oyW" customClass="BubbleCell" customModule="QuickTest" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="260"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Oi2-T7-oyW" id="gQY-hx-B2I">
<rect key="frame" x="0.0" y="0.0" width="375" height="260"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="h2Z-Bt-MGu">
<rect key="frame" x="16" y="11" width="343" height="238"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="wrN-dr-6PW">
<rect key="frame" x="8" y="12" width="327" height="214"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Aio-Ve-8b1">
<rect key="frame" x="0.0" y="0.0" width="327" height="165.5"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="Label" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="83w-nH-MFV">
<rect key="frame" x="0.0" y="171.5" width="327" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="13:50 - sent" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3MO-It-xQw">
<rect key="frame" x="0.0" y="198" width="327" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" systemColor="systemGreenColor"/>
<constraints>
<constraint firstItem="wrN-dr-6PW" firstAttribute="top" secondItem="h2Z-Bt-MGu" secondAttribute="top" constant="12" id="61F-T7-VXd"/>
<constraint firstAttribute="trailing" secondItem="wrN-dr-6PW" secondAttribute="trailing" constant="8" id="Aso-zu-ZPc"/>
<constraint firstItem="wrN-dr-6PW" firstAttribute="leading" secondItem="h2Z-Bt-MGu" secondAttribute="leading" constant="8" id="bsG-sY-260"/>
<constraint firstAttribute="bottom" secondItem="wrN-dr-6PW" secondAttribute="bottom" constant="12" id="oAO-Jt-UX3"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.897361517" green="0.8974906802" blue="0.89733326440000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailingMargin" relation="greaterThanOrEqual" secondItem="h2Z-Bt-MGu" secondAttribute="trailing" id="6hf-N2-14b"/>
<constraint firstAttribute="bottomMargin" secondItem="h2Z-Bt-MGu" secondAttribute="bottom" id="FxF-PE-6iW"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="gQY-hx-B2I" secondAttribute="leadingMargin" id="Wsa-eO-InO"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="top" secondItem="gQY-hx-B2I" secondAttribute="topMargin" id="ZYU-hS-2Pl"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="trailing" secondItem="gQY-hx-B2I" secondAttribute="trailingMargin" id="edX-9l-Ye2"/>
<constraint firstItem="h2Z-Bt-MGu" firstAttribute="leading" secondItem="gQY-hx-B2I" secondAttribute="leadingMargin" id="s0J-rx-Rzx"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="bubbleView" destination="h2Z-Bt-MGu" id="uJ0-t9-ZQ9"/>
<outlet property="messageLabel" destination="83w-nH-MFV" id="pEd-Gg-49x"/>
<outlet property="myImageView" destination="Aio-Ve-8b1" id="qJQ-G9-Qc6"/>
<outlet property="receivedConstraint" destination="s0J-rx-Rzx" id="fCI-9h-2V1"/>
<outlet property="sentConstraint" destination="edX-9l-Ye2" id="KKm-FT-Zcq"/>
<outlet property="timeLabel" destination="3MO-It-xQw" id="bxt-vZ-c2v"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="bubble80Cell" rowHeight="260" id="DAc-Zm-a8s" customClass="BubbleCell" customModule="QuickTest" customModuleProvider="target">
<rect key="frame" x="0.0" y="288" width="375" height="260"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="DAc-Zm-a8s" id="te5-Rn-aLa">
<rect key="frame" x="0.0" y="0.0" width="375" height="260"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lFi-s6-a3X">
<rect key="frame" x="16" y="11" width="300" height="238"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="HX0-dn-sRz">
<rect key="frame" x="8" y="12" width="284" height="214"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Xsw-i1-9mU">
<rect key="frame" x="0.0" y="0.0" width="284" height="165.5"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="Label" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6Zs-Af-RNQ">
<rect key="frame" x="0.0" y="171.5" width="284" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" text="13:50 - sent" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7nV-rU-i4W">
<rect key="frame" x="0.0" y="198" width="284" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" systemColor="systemGreenColor"/>
<constraints>
<constraint firstItem="HX0-dn-sRz" firstAttribute="leading" secondItem="lFi-s6-a3X" secondAttribute="leading" constant="8" id="6Kk-f4-tiB"/>
<constraint firstItem="HX0-dn-sRz" firstAttribute="top" secondItem="lFi-s6-a3X" secondAttribute="top" constant="12" id="7H5-6V-Ag0"/>
<constraint firstAttribute="trailing" secondItem="HX0-dn-sRz" secondAttribute="trailing" constant="8" id="Czf-wx-QBQ"/>
<constraint firstAttribute="bottom" secondItem="HX0-dn-sRz" secondAttribute="bottom" constant="12" id="edZ-aP-M1N"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.897361517" green="0.8974906802" blue="0.89733326440000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="lFi-s6-a3X" firstAttribute="trailing" secondItem="te5-Rn-aLa" secondAttribute="trailingMargin" id="Ua5-F4-YR5"/>
<constraint firstAttribute="bottomMargin" secondItem="lFi-s6-a3X" secondAttribute="bottom" id="WKr-87-LJK"/>
<constraint firstItem="lFi-s6-a3X" firstAttribute="leading" secondItem="te5-Rn-aLa" secondAttribute="leadingMargin" id="h4U-ie-xYq"/>
<constraint firstItem="lFi-s6-a3X" firstAttribute="width" relation="lessThanOrEqual" secondItem="te5-Rn-aLa" secondAttribute="width" multiplier="0.8" id="sKr-Xc-5bn"/>
<constraint firstItem="lFi-s6-a3X" firstAttribute="top" secondItem="te5-Rn-aLa" secondAttribute="topMargin" id="ueL-NI-qoX"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="bubbleView" destination="lFi-s6-a3X" id="5qj-C0-Uf3"/>
<outlet property="messageLabel" destination="6Zs-Af-RNQ" id="YTU-M9-s7P"/>
<outlet property="myImageView" destination="Xsw-i1-9mU" id="Unr-HS-Iv1"/>
<outlet property="receivedConstraint" destination="h4U-ie-xYq" id="tCy-cc-uHa"/>
<outlet property="sentConstraint" destination="Ua5-F4-YR5" id="Kgg-gY-JCv"/>
<outlet property="timeLabel" destination="7nV-rU-i4W" id="GUX-T1-4Nc"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="t48-nh-14V" id="3oa-OS-rO8"/>
<outlet property="delegate" destination="t48-nh-14V" id="7Ua-sV-mwS"/>
</connections>
</tableView>
<navigationItem key="navigationItem" id="fpm-tv-1pb"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2On-8d-2Kp" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-1447.2" y="-749.7751124437782"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemGreenColor">
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
Edit
Worth noting -- if we replace these two lines in fillData():
sentConstraint.isActive = msg.type == .sent
receivedConstraint.isActive = msg.type == .received
with these:
sentConstraint.priority = msg.type == .sent ? .defaultHigh : .defaultLow
receivedConstraint.priority = msg.type == .received ? .defaultHigh : .defaultLow
we'll accomplish the same goal.
Without seeing your actual layout (difficult to decipher the "description of all constraints" you posted), and without seeing the code you are using, it's tough to say why that wasn't working for you.

Need constraints for y position or height when height is unambiguous with stack views in stack views

I created a "TitleDetails" view below and I'd like to stack that titleDetails view into another reusable view. There are no errors thrown for the TitleDetails constraints. I'd just like to stack 2 TitleDetails views into a new view.
However, when I do the constraints it appears I need the Y position for height, however the height of titleDetails should be determined by its contents and the space between the two is constrained as well. So I'm not seeing where the ambiguity is coming from.
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" 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="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="TitleDetails" customModule="WholeVC" customModuleProvider="target">
<connections>
<outlet property="detailsLabel" destination="pjO-IR-TuP" id="EkZ-wc-LOm"/>
<outlet property="stackBottom" destination="W1y-Me-M1S" id="ykw-d7-bz9"/>
<outlet property="stackLeading" destination="6n3-Qg-845" id="ghK-h8-OBL"/>
<outlet property="stackTop" destination="Ey8-Pq-GRr" id="WOw-Q0-zc2"/>
<outlet property="stackTrailing" destination="m9b-I7-Nwj" id="ly8-lY-3zf"/>
<outlet property="stackView" destination="pIM-2q-cOU" id="LvK-Yk-LHf"/>
<outlet property="titleLabel" destination="G5U-AG-1Se" id="4KM-9f-LQA"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="208" height="72"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="pIM-2q-cOU">
<rect key="frame" x="0.0" y="0.0" width="208" height="72"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="1000" verticalHuggingPriority="1000" text="Title" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="G5U-AG-1Se">
<rect key="frame" x="0.0" y="0.0" width="36.5" height="72"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Details Details Details" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pjO-IR-TuP">
<rect key="frame" x="41.5" y="0.0" width="166.5" height="72"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="pjO-IR-TuP" firstAttribute="width" relation="greaterThanOrEqual" secondItem="G5U-AG-1Se" secondAttribute="width" id="EGR-ZT-2ID"/>
</constraints>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="pIM-2q-cOU" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="6n3-Qg-845"/>
<constraint firstItem="pIM-2q-cOU" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Ey8-Pq-GRr"/>
<constraint firstAttribute="bottom" secondItem="pIM-2q-cOU" secondAttribute="bottom" id="W1y-Me-M1S"/>
<constraint firstAttribute="trailing" secondItem="pIM-2q-cOU" secondAttribute="trailing" id="m9b-I7-Nwj"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="94.20289855072464" y="-113.16964285714285"/>
</view>
<view contentMode="scaleToFill" id="Xof-7G-Flv">
<rect key="frame" x="0.0" y="0.0" width="355" height="279"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="awM-nF-Vev" customClass="TitleDetails" customModule="WholeVC" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="355" height="103"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mcx-Fg-GMg" customClass="TitleDetails" customModule="WholeVC" customModuleProvider="target">
<rect key="frame" x="0.0" y="172" width="355" height="107"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="art-6S-teo"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="awM-nF-Vev" firstAttribute="leading" secondItem="Xof-7G-Flv" secondAttribute="leading" id="3Sp-vC-vfu"/>
<constraint firstItem="awM-nF-Vev" firstAttribute="trailing" secondItem="Xof-7G-Flv" secondAttribute="trailing" id="L4H-5I-T0j"/>
<constraint firstItem="awM-nF-Vev" firstAttribute="top" secondItem="Xof-7G-Flv" secondAttribute="top" id="Xcm-9t-hJx"/>
<constraint firstItem="mcx-Fg-GMg" firstAttribute="top" secondItem="awM-nF-Vev" secondAttribute="bottom" constant="69" id="Yh4-pM-WP6"/>
<constraint firstItem="mcx-Fg-GMg" firstAttribute="trailing" secondItem="Xof-7G-Flv" secondAttribute="trailing" id="dUB-H0-Zm1"/>
<constraint firstItem="mcx-Fg-GMg" firstAttribute="bottom" secondItem="Xof-7G-Flv" secondAttribute="bottom" id="feT-Rh-Vs7"/>
<constraint firstItem="mcx-Fg-GMg" firstAttribute="leading" secondItem="Xof-7G-Flv" secondAttribute="leading" id="pD5-5k-VJf"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="94.927536231884062" y="67.96875"/>
</view>
</objects>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
What you've shown would be very easy to implement via code, rather than XIB files.
However, the reason you're getting the ambiguity is because interface builder cannot determine the intrinsic height as you have designed it.
IF your current implementation gives you the desired layout at run-time, you can get rid of the "ambiguous" errors / warnings by giving your top TitleDetails view a "Placeholder" intrinsic height.
Select the view, and then in the Size Inspector pane:

Stack View breaks when switching to vertical axis

As a continuation of this problem. When I actually apply the constraints in a ViewController, I am finding that actually switching the axis to Vertical totally breaks the constraints.
Here is the before. It's looking proper.
Now here is after switching to vertical.
Totally baffled as to why this happens...
It says I need another width constraint, however the Stack View already has 2 width constraints:
Why is this happening and how can I fix this?
Here is my code:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="Test2Part" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" ambiguous="YES" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="VP4-UJ-ETA">
<rect key="frame" x="0.0" y="424" width="0.0" height="48"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="1000" verticalHuggingPriority="1000" text="asdlfkjlkjalskdjflakjsdlkfjalkjsdflkjasldkfjalkjsdflkj" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xej-eS-5Sd">
<rect key="frame" x="0.0" y="0.0" width="0.0" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Xj4-8Q-inE">
<rect key="frame" x="0.0" y="27.5" width="0.0" height="20.5"/>
<string key="text">asldkfjalkjsdflkjasldkjfalkjsdflkjasldkjflakjsdlfkjalskdjflaqkjsdlfkjalksdjflaksdlfkjalskdjflakjsdlfkjalsdkjflakjsdflkjasldkjflakjsdflkjasdf</string>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="Xj4-8Q-inE" firstAttribute="width" relation="greaterThanOrEqual" secondItem="Xej-eS-5Sd" secondAttribute="width" multiplier="1.2" id="xrh-Tq-uYT"/>
</constraints>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="VP4-UJ-ETA" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="ML4-KP-VmW"/>
<constraint firstItem="VP4-UJ-ETA" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="ZUI-PV-Ofm"/>
<constraint firstItem="VP4-UJ-ETA" firstAttribute="width" secondItem="8bC-Xf-vdC" secondAttribute="width" id="aA4-hD-Jye"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="26" y="89"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

How to control depth in UIKit?

I am having an issue with the "depth" of views in UIKit. The ImageView is on top of the TextField, but I want the converse: the text field on top. Below goes an image showing the problem:
FWIW: In SwiftUI, there is ZStack which allows one to easily define what goes on top of what, but I am looking for a solution in UIKit as this project is for a course I am doing to learn UIKit.
The project is on GitHub and is called MemeEditor. This link goes to a commit that presents the aforementioned problem.
Thanks!
I am looking for a solution in UIKit as this project is for a course I am doing to learn UIKit.
From your question, it sounds like you're looking for a way to do this in code. UIView contains a number of methods that let you change the z-order of subviews, such as insertSubview(_:aboveSubview:) and insertSubview(_:belowSubview:), but since you already have two existing subviews you can use exchangeSubview(at:withSubviewAt:) to just swap the positions of the text view and image in the subviews array.
I actually found two solutions:
Code Solution
From:
How can I bring a view in front of another view, in Swift?
With that, I had to add to the View Controller the line
self.view.bringSubviewToFront(textField)
Diff here
Storyboard solution
After a few days, I got feedback on the project and I understood how to do this in the storyboard. Views will show on top when they after down in the hierarchy on the storyboard.
So, I changed from:
to:
and the code worked. FWIW the diff is:
diff --git a/MemeEditor/Base.lproj/Main.storyboard b/MemeEditor/Base.lproj/Main.storyboard
index c4fbb55..18400ce 100644
--- a/MemeEditor/Base.lproj/Main.storyboard
+++ b/MemeEditor/Base.lproj/Main.storyboard
## -16,6 +16,14 ##
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
+ <stackView opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="l0u-Hb-3mT">
+ <rect key="frame" x="0.0" y="44" width="414" height="818"/>
+ <subviews>
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="JJT-iB-9fc">
+ <rect key="frame" x="0.0" y="0.0" width="414" height="818"/>
+ </imageView>
+ </subviews>
+ </stackView>
<textField contentMode="center" contentHorizontalAlignment="center" contentVerticalAlignment="center" placeholder="TOP MESSAGE" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="cOM-zN-T9a" userLabel="Top Text Field">
<rect key="frame" x="10" y="84" width="394" height="49.5"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
## -28,14 +36,6 ##
<fontDescription key="fontDescription" name="HelveticaNeue-CondensedBlack" family="Helvetica Neue" pointSize="40"/>
<textInputTraits key="textInputTraits" autocapitalizationType="allCharacters"/>
</textField>
- <stackView opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="l0u-Hb-3mT">
- <rect key="frame" x="0.0" y="44" width="414" height="818"/>
- <subviews>
- <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="JJT-iB-9fc">
- <rect key="frame" x="0.0" y="0.0" width="414" height="818"/>
- </imageView>
- </subviews>
- </stackView>
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OY4-30-dsi">
<rect key="frame" x="0.0" y="813" width="414" height="49"/>
<items>
Copy the view you want to be front (⌘C), delete the old one and paste it (⌘V).