Search code examples
uiviewxamarin.iosstoryboarduistackview

Right alignment of controls inside a horizontally oriented stackview in uistoryboard


I have a StackView (Card View) with vertical orientation, alignment and distribution are "Fill".

Screenshot from Xcode

Inside that I have a few more StackViews with horizontal orientation and a few other controls. In that, the last StackView with Horizontal Orientation, Alignment = Top and Distribution = Fill, has two buttons for "Save" and "Cancel"

XML for last stackview:

<stackView opaque="NO" contentMode="right" alignment="top" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="qk0-Aa-LVy">
<rect key="frame" x="0.0" y="301" width="414" height="51"/>
<subviews>
    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="wordWrap" translatesAutoresizingMaskIntoConstraints="NO" id="TzA-jj-KRx">
        <rect key="frame" x="0.0" y="0.0" width="199.66666666666666" height="31"/>
        <inset key="contentEdgeInsets" minX="10" minY="10" maxX="10" maxY="10"/>
        <state key="normal" title="Button"/>
        <buttonConfiguration key="configuration" style="plain" title="Save" buttonSize="medium"/>
    </button>
    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xHU-No-XcV">
        <rect key="frame" x="214.66666666666663" y="0.0" width="199.33333333333337" height="31"/>
        <state key="normal" title="Button"/>
        <buttonConfiguration key="configuration" style="plain" title="Cancel"/>
    </button>
</subviews>
<constraints>
    <constraint firstAttribute="bottomMargin" secondItem="TzA-jj-KRx" secondAttribute="bottom" constant="20" id="d5Z-DX-Keg"/>
</constraints>

Screenshot with stackview properties

I want the two buttons to right align and I don't know how to get that. I use Xamarin.iOS.

Please note, There may be some unwanted constrains and other code as this was my first learning project. Please let me know more lines from xml is needed. Thanks in advance.


Solution

  • First tip: Change the default names of your UI elements to make it easy to understand the Hierarchy in the Document Outline pane.

    It looks like you have a lot of unnecessary constraints...

    I laid out a controller to match yours (well, at least close) - here's how it looks:

    enter image description here

    The horizontal stack view containing the Save/Cancel buttons is an arranged subview of Card Stack View ... which has Alignment: Fill which means the Buttons Stack View will be stretched to the full width.

    If you want the buttons to "right align" you need to embed Buttons Stack View in a UIView - I'll name it BtnStack Holder View - and constrain Buttons Stack View Top, Bottom & Trailing (but not Leading).

    That gives us this (I gave BtnStack Holder View a Yellow background to make it easy to see):

    enter image description here

    Here is the source for that Storyboard:

    <?xml version="1.0" encoding="UTF-8"?>
    <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
        <device id="retina4_7" orientation="portrait" appearance="light"/>
        <dependencies>
            <deployment identifier="iOS"/>
            <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
            <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="s0d-6b-0kx">
                <objects>
                    <viewController id="Y6W-OH-hqX" sceneMemberID="viewController">
                        <view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
                            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                            <subviews>
                                <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="R7A-M2-45j" userLabel="Root Stack View">
                                    <rect key="frame" x="0.0" y="20" width="375" height="334"/>
                                    <subviews>
                                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cxs-Xz-vJJ" userLabel="Logo Image View">
                                            <rect key="frame" x="0.0" y="0.0" width="375" height="60"/>
                                            <constraints>
                                                <constraint firstAttribute="height" constant="60" id="5bf-RF-cow"/>
                                            </constraints>
                                        </imageView>
                                        <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="IV2-Ac-KTt" userLabel="Card Stack View">
                                            <rect key="frame" x="0.0" y="72" width="375" height="262"/>
                                            <subviews>
                                                <stackView opaque="NO" contentMode="scaleToFill" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="tkJ-N8-lmn" userLabel="A Stack View">
                                                    <rect key="frame" x="0.0" y="0.0" width="375" height="31"/>
                                                    <subviews>
                                                        <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" horizontalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1iP-4F-fXh">
                                                            <rect key="frame" x="0.0" y="0.0" width="51" height="31"/>
                                                        </switch>
                                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Allow me to track your location" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LdZ-fZ-8eB">
                                                            <rect key="frame" x="61" y="0.0" width="314" height="31"/>
                                                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                            <nil key="textColor"/>
                                                            <nil key="highlightedColor"/>
                                                        </label>
                                                    </subviews>
                                                </stackView>
                                                <stackView opaque="NO" contentMode="scaleToFill" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="NbU-Ac-LPE" userLabel="B Stack View">
                                                    <rect key="frame" x="0.0" y="47" width="375" height="31"/>
                                                    <subviews>
                                                        <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" horizontalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wJh-5f-Rzb">
                                                            <rect key="frame" x="0.0" y="0.0" width="51" height="31"/>
                                                        </switch>
                                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Allow me to use the camera to scan QR codes" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VhU-SK-Ehb">
                                                            <rect key="frame" x="61" y="0.0" width="314" height="31"/>
                                                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                            <nil key="textColor"/>
                                                            <nil key="highlightedColor"/>
                                                        </label>
                                                    </subviews>
                                                </stackView>
                                                <stackView opaque="NO" contentMode="scaleToFill" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="4Eh-cj-Eyk" userLabel="C Stack View">
                                                    <rect key="frame" x="0.0" y="94" width="375" height="31"/>
                                                    <subviews>
                                                        <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" horizontalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cbM-V2-q1x">
                                                            <rect key="frame" x="0.0" y="0.0" width="51" height="31"/>
                                                        </switch>
                                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Allow me to use NFC connections" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="i7Y-61-XAS">
                                                            <rect key="frame" x="61" y="0.0" width="314" height="31"/>
                                                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                            <nil key="textColor"/>
                                                            <nil key="highlightedColor"/>
                                                        </label>
                                                    </subviews>
                                                </stackView>
                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Customer identifier:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ODr-EE-p48" userLabel="Host Name Label">
                                                    <rect key="frame" x="0.0" y="141" width="375" height="20.5"/>
                                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                    <nil key="textColor"/>
                                                    <nil key="highlightedColor"/>
                                                </label>
                                                <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="temp" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="GFT-dj-GNZ" userLabel="Host Name Text">
                                                    <rect key="frame" x="0.0" y="177.5" width="375" height="34"/>
                                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
                                                    <textInputTraits key="textInputTraits"/>
                                                </textField>
                                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kFD-Sc-UIQ" userLabel="BtnStack Holder View">
                                                    <rect key="frame" x="0.0" y="227.5" width="375" height="34.5"/>
                                                    <subviews>
                                                        <stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Xdd-6y-H1j" userLabel="Buttons Stack View">
                                                            <rect key="frame" x="214" y="0.0" width="161" height="34.5"/>
                                                            <subviews>
                                                                <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2Yh-up-7dE">
                                                                    <rect key="frame" x="0.0" y="0.0" width="76.5" height="34.5"/>
                                                                    <state key="normal" title="Button"/>
                                                                    <buttonConfiguration key="configuration" style="plain" title="Save"/>
                                                                </button>
                                                                <button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="V7g-sC-sGu">
                                                                    <rect key="frame" x="84.5" y="0.0" width="76.5" height="34.5"/>
                                                                    <state key="normal" title="Button"/>
                                                                    <buttonConfiguration key="configuration" style="plain" title="Cancel"/>
                                                                </button>
                                                            </subviews>
                                                        </stackView>
                                                    </subviews>
                                                    <color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                    <constraints>
                                                        <constraint firstItem="Xdd-6y-H1j" firstAttribute="top" secondItem="kFD-Sc-UIQ" secondAttribute="top" id="LlS-5v-cXp"/>
                                                        <constraint firstAttribute="bottom" secondItem="Xdd-6y-H1j" secondAttribute="bottom" id="buF-cZ-29y"/>
                                                        <constraint firstAttribute="trailing" secondItem="Xdd-6y-H1j" secondAttribute="trailing" id="lVb-UW-eYo"/>
                                                    </constraints>
                                                </view>
                                            </subviews>
                                        </stackView>
                                    </subviews>
                                </stackView>
                            </subviews>
                            <viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                            <constraints>
                                <constraint firstItem="R7A-M2-45j" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" id="6QS-yP-c87"/>
                                <constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="R7A-M2-45j" secondAttribute="trailing" id="fFV-cY-YXj"/>
                                <constraint firstItem="R7A-M2-45j" firstAttribute="top" secondItem="vDu-zF-Fre" secondAttribute="top" id="yAh-lU-Ojw"/>
                            </constraints>
                        </view>
                    </viewController>
                    <placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
                </objects>
                <point key="canvasLocation" x="28" y="4.9475262368815596"/>
            </scene>
        </scenes>
        <resources>
            <systemColor name="systemBackgroundColor">
                <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
            </systemColor>
        </resources>
    </document>