StackView 内的 Xcode 11 ScrollView

Posted

技术标签:

【中文标题】StackView 内的 Xcode 11 ScrollView【英文标题】:Xcode 11 ScrollView inside StackView 【发布时间】:2019-11-13 11:32:54 【问题描述】:

也许有人可以帮助我解决我正在使用 InterfaceBuilder 和 Auto Layout 解决的问题。

我有一个 containerView(黄色),其中有一个视图控制器,该控制器的视图中填充了 StackView(蓝色)。这个 StackView 用 = 0 固定在顶部、左边、右边,用 >= 0 固定到底部。

然后在 StackView 内需要有一个 ScrollView(橙色)(垂直滚动),我在运行时添加子视图(1 到 20 个标签之间)。此 ScrollView 应占用视图的所有剩余空间,并且最小高度为 100 像素。

当我运行应用程序时,ScrollView 是不可滚动的。并且堆栈视图的第一部分的内容也被推出视图(在顶部)。

我将 Scrollview 设置为 Content Compression Resistance Priority 为 1000。没有变化。

我迷路了,我该如何解决这个问题,非常感谢任何帮助/指导。

这里有一些布局,应该是什么样子:

【问题讨论】:

黄色和蓝色视图之间的间距如何?它是如何确定的? 我有一个带有 NavigationBar 的 View Controller,这个 Vc 里面是黄色的 ViewContainer。 10px 到 NavBar 和边。里面是在 0px 处固定到超级视图的 StackView(蓝色)。所以黄色空间其实有点误导,我用它来显示层次结构。 将 ScrollView 与 Stack 视图分开会更好吗?顶部的堆栈视图,底部的滚动视图,其中的堆栈视图?这可能是一种解决方法,但它会对我做错的事情很感兴趣。我觉得我对 AutoLayout 太笨了。 显然您想从堆栈视图的其余内容中水平“插入”滚动视图。所以最好不要放到stack view中。 好的,谢谢,我认为这应该是可能的。所以基本上如果我想要标签 |滚动视图 |标签,然后我需要 StackView |滚动视图 |堆栈视图?感谢您的帮助,非常感谢。 【参考方案1】:

这是展示您的观点的一种方式...

请注意,“动态内容”标签是 scrollView 的子视图,但 不是 在 stackView 中...我从您的图片中假设它是某种。它的约束用于定义 scrollView 的 contentSize 的顶部/前导/尾部和宽度。 “Dyna Stack”视图将确定高度/底部。

添加几个标签后的结果:

在添加足够的滚动标签后:

这里是 Storyboard 的来源(以便于查看所有布局元素):

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15400" targetRuntime="ios.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15404"/>
        <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="Maverick" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0"  />
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="117-6U-FYG">
                                <rect key="frame" x="40" y="40"  />
                                <subviews>
                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Vf7-GC-TmS">
                                        <rect key="frame" x="0.0" y="0.0"  />
                                        <color key="backgroundColor" systemColor="systemBlueColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <state key="normal" title="Add">
                                            <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        </state>
                                        <connections>
                                            <action selector="addTapped:" destination="BYZ-38-t0r" eventType="touchUpInside" id="guo-Zq-b1a"/>
                                        </connections>
                                    </button>
                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3Kz-xL-gyr">
                                        <rect key="frame" x="157.5" y="0.0"  />
                                        <color key="backgroundColor" systemColor="systemBlueColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <state key="normal" title="Remove">
                                            <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        </state>
                                        <connections>
                                            <action selector="removeTapped:" destination="BYZ-38-t0r" eventType="touchUpInside" id="xv6-bC-c5X"/>
                                        </connections>
                                    </button>
                                </subviews>
                            </stackView>
                            <containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jv2-F6-WcO">
                                <rect key="frame" x="20" y="110"  />
                                <connections>
                                    <segue destination="BU8-S1-sGS" kind="embed" id="pLu-Bb-fDK"/>
                                </connections>
                            </containerView>
                        </subviews>
                        <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
                        <constraints>
                            <constraint firstItem="117-6U-FYG" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="40" id="3D7-vE-QG7"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="117-6U-FYG" secondAttribute="trailing" constant="40" id="CK8-KW-Pm2"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="jv2-F6-WcO" secondAttribute="bottom" constant="40" id="E2H-NW-tUx"/>
                            <constraint firstItem="117-6U-FYG" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="JnT-dj-EtL"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="jv2-F6-WcO" secondAttribute="trailing" constant="20" id="V70-Qo-9Ea"/>
                            <constraint firstItem="117-6U-FYG" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="40" id="VGK-Ol-Vqv"/>
                            <constraint firstItem="jv2-F6-WcO" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" constant="20" id="py5-VV-PzD"/>
                            <constraint firstItem="jv2-F6-WcO" firstAttribute="top" secondItem="117-6U-FYG" secondAttribute="bottom" constant="40" id="ul2-Rp-xdk"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="-718" y="90"/>
        </scene>
        <!--Sub View Controller-->
        <scene sceneID="ofE-9O-3Zb">
            <objects>
                <viewController id="BU8-S1-sGS" customClass="SubViewController" customModule="Maverick" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="ZSF-IV-JZX">
                        <rect key="frame" x="0.0" y="0.0"  />
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eDt-4V-gxm" userLabel="Just to Show Stack Frame">
                                <rect key="frame" x="32" y="16"  />
                                <color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                            </view>
                            <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="31" translatesAutoresizingMaskIntoConstraints="NO" id="QEf-Fd-Vyo">
                                <rect key="frame" x="36" y="20"  />
                                <subviews>
                                    <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="24" translatesAutoresizingMaskIntoConstraints="NO" id="V9q-T5-bad">
                                        <rect key="frame" x="0.0" y="0.0"  />
                                        <subviews>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BPT-QG-EeY">
                                                <rect key="frame" x="0.0" y="0.0"  />
                                                <color key="backgroundColor" red="0.99336069822311401" green="0.89430927864019549" blue="0.94426094444331177" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="VLQ-n9-nfD">
                                                <rect key="frame" x="0.0" y="44.5"  />
                                                <subviews>
                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label 1" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Npr-AI-qHW">
                                                        <rect key="frame" x="0.0" y="0.0"  />
                                                        <color key="backgroundColor" red="0.99336069822311401" green="0.89430927864019549" blue="0.94426094444331177" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                        <nil key="textColor"/>
                                                        <nil key="highlightedColor"/>
                                                    </label>
                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label 2" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hfl-Ub-zjq">
                                                        <rect key="frame" x="0.0" y="28.5"  />
                                                        <color key="backgroundColor" red="0.99336069822311401" green="0.89430927864019549" blue="0.94426094444331177" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                        <nil key="textColor"/>
                                                        <nil key="highlightedColor"/>
                                                    </label>
                                                </subviews>
                                            </stackView>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label 3" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NpO-cr-hPg">
                                                <rect key="frame" x="0.0" y="117.5"  />
                                                <color key="backgroundColor" red="0.99336069822311401" green="0.89430927864019549" blue="0.94426094444331177" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                        </subviews>
                                    </stackView>
                                    <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LuK-Bh-b6R">
                                        <rect key="frame" x="0.0" y="169"  />
                                        <subviews>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Dynamic Content" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="33O-PE-pv7">
                                                <rect key="frame" x="8" y="8"  />
                                                <color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="eH7-Hu-tJN">
                                                <rect key="frame" x="8" y="48.5"  />
                                                <subviews>
                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Layout design labels" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="G4E-pX-zmu">
                                                        <rect key="frame" x="0.0" y="0.0"  />
                                                        <color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                        <nil key="textColor"/>
                                                        <nil key="highlightedColor"/>
                                                    </label>
                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Removed in viewDidLoad()" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bzC-dL-w38">
                                                        <rect key="frame" x="0.0" y="28.5"  />
                                                        <color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                        <nil key="textColor"/>
                                                        <nil key="highlightedColor"/>
                                                    </label>
                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sub-Label 3" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vzO-vG-JOF">
                                                        <rect key="frame" x="0.0" y="57"  />
                                                        <color key="backgroundColor" red="0.45009386540000001" green="0.98132258650000004" blue="0.4743030667" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                        <nil key="textColor"/>
                                                        <nil key="highlightedColor"/>
                                                    </label>
                                                </subviews>
                                            </stackView>
                                        </subviews>
                                        <color key="backgroundColor" systemColor="systemYellowColor" red="1" green="0.80000000000000004" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <constraints>
                                            <constraint firstItem="eH7-Hu-tJN" firstAttribute="centerX" secondItem="33O-PE-pv7" secondAttribute="centerX" id="CCi-45-C2R"/>
                                            <constraint firstItem="eH7-Hu-tJN" firstAttribute="top" secondItem="33O-PE-pv7" secondAttribute="bottom" constant="20" id="HWf-Pp-eJo"/>
                                            <constraint firstItem="33O-PE-pv7" firstAttribute="top" secondItem="Z4n-lt-83b" secondAttribute="top" constant="8" id="QGO-EC-a1N"/>
                                            <constraint firstItem="33O-PE-pv7" firstAttribute="trailing" secondItem="Z4n-lt-83b" secondAttribute="trailing" constant="8" id="fz4-KU-6BP"/>
                                            <constraint firstItem="Z4n-lt-83b" firstAttribute="bottom" secondItem="eH7-Hu-tJN" secondAttribute="bottom" constant="8" id="lkW-Mv-xeJ"/>
                                            <constraint firstItem="33O-PE-pv7" firstAttribute="width" secondItem="KFx-Yf-vSh" secondAttribute="width" constant="-16" id="loG-jL-d0d"/>
                                            <constraint firstItem="33O-PE-pv7" firstAttribute="leading" secondItem="Z4n-lt-83b" secondAttribute="leading" constant="8" id="qxx-0L-bkh"/>
                                            <constraint firstItem="eH7-Hu-tJN" firstAttribute="width" secondItem="33O-PE-pv7" secondAttribute="width" id="tKW-fj-A10"/>
                                        </constraints>
                                        <viewLayoutGuide key="contentLayoutGuide" id="Z4n-lt-83b"/>
                                        <viewLayoutGuide key="frameLayoutGuide" id="KFx-Yf-vSh"/>
                                    </scrollView>
                                </subviews>
                            </stackView>
                        </subviews>
                        <color key="backgroundColor" red="0.99953407049999998" green="0.98835557699999999" blue="0.47265523669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="eDt-4V-gxm" firstAttribute="height" secondItem="QEf-Fd-Vyo" secondAttribute="height" constant="8" id="3Br-Qe-Txd"/>
                            <constraint firstAttribute="trailingMargin" secondItem="QEf-Fd-Vyo" secondAttribute="trailing" constant="20" id="4pW-Bm-Akv"/>
                            <constraint firstItem="QEf-Fd-Vyo" firstAttribute="leading" secondItem="ZSF-IV-JZX" secondAttribute="leadingMargin" constant="20" id="CMn-y9-bUf"/>
                            <constraint firstItem="eDt-4V-gxm" firstAttribute="centerY" secondItem="QEf-Fd-Vyo" secondAttribute="centerY" id="D3l-c7-3Hc"/>
                            <constraint firstItem="eDt-4V-gxm" firstAttribute="centerX" secondItem="QEf-Fd-Vyo" secondAttribute="centerX" id="Ntf-HA-sIt"/>
                            <constraint firstItem="eDt-4V-gxm" firstAttribute="width" secondItem="QEf-Fd-Vyo" secondAttribute="width" constant="8" id="W6S-Fg-hru"/>
                            <constraint firstItem="QEf-Fd-Vyo" firstAttribute="top" secondItem="ZSF-IV-JZX" secondAttribute="topMargin" constant="20" id="cXx-bE-SaR"/>
                            <constraint firstAttribute="bottomMargin" secondItem="QEf-Fd-Vyo" secondAttribute="bottom" constant="20" id="tOm-gp-iUg"/>
                        </constraints>
                    </view>
                    <connections>
                        <outlet property="dynaStack" destination="eH7-Hu-tJN" id="6WL-HO-RQF"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="EQR-GS-QRJ" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="-20" y="90"/>
        </scene>
    </scenes>
</document>

以及本例使用的代码:

//
//  ViewController.swift
//
//  Created by Don Mag on 11/13/19.
//

import UIKit

class ViewController: UIViewController 

    var subVC: SubViewController?

    override func viewDidLoad() 
        super.viewDidLoad()
    

    @IBAction func addTapped(_ sender: Any) 
        subVC?.addLabel()
    

    @IBAction func removeTapped(_ sender: Any) 
        subVC?.removeLabel()
    

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        if let vc = segue.destination as? SubViewController 
            subVC = vc
        
    



class SubViewController: UIViewController 

    @IBOutlet weak var dynaStack: UIStackView!

    override func viewDidLoad() 
        super.viewDidLoad()

        // remove design-time labels
        dynaStack.arrangedSubviews.forEach 
            $0.removeFromSuperview()
        

    

    func addLabel() -> Void 
        let v = UILabel()
        v.backgroundColor = .green
        v.text = "Sub-Label \(dynaStack.arrangedSubviews.count + 1)"
        dynaStack.addArrangedSubview(v)

        // dispatch scroll-to-bottom on main thread
        // need to do this so contentSize is calculated after
        // new label has been added
        if let sv = dynaStack.superview as? UIScrollView 
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) 
                let bottomOffset = CGPoint(x: 0, y: sv.contentSize.height - sv.bounds.size.height + sv.contentInset.bottom)
                if(bottomOffset.y > 0) 
                    sv.setContentOffset(bottomOffset, animated: true)
                
            
        
    

    func removeLabel() -> Void 
        if dynaStack.arrangedSubviews.count > 0 
            dynaStack.arrangedSubviews.last?.removeFromSuperview()
        
    


【讨论】:

像魅力一样工作!非常感谢您花时间帮助我,非常感谢!我仍然需要习惯 AutoLayout,它让我一遍又一遍地头疼。

以上是关于StackView 内的 Xcode 11 ScrollView的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 Interface Builder Xcode 中的 stackview 错误问题?

在水平 StackView 内的 TextView 中删除 Padding top

collectionview 或 uitableview 内的 Stackview

如何在情节提要 Xcode 11 中的视图之间将边距设置为零

Xcode/Stackview,空标签在堆栈视图中吓坏了?

StackView 内的 CollectionView