【问题标题】:UIScrollView + UITableView + AutolayoutUIScrollView + UITableView + 自动布局
【发布时间】:2021-11-17 02:03:54
【问题描述】:

我已经读过,不建议在 UIScrollView 内部使用 UITableView,但是我想对其进行测试并切换回不使用滚动视图作为最后一个选项的 UITableView 的想法。

我尝试的是:

UIView => MAIN VIEW of the UIViewController
 - UIView => FOR a fixed header in the view
 -- UIButton on the right of this view
 - UIScrollView => For the rest of the view
 -- UIView => The container view of the UIScrollView
 --- UILabel => Top Label
 --- UITableView => The table
 --- UILabel => Bottom Label

我在 UITableView 中设置了禁用滚动,因为我在 ScrollView 中有滚动。我想我设置了所有的约束,但 Xcode 仍然抱怨: ScrollView 需要限制可滚动内容的宽度 ScrollView 需要对可滚动内容高度进行约束

如果我不解决这个问题,我在表格视图中看不到任何行:

如果我让 Xcode 解决约束问题:

但是你不能滚动 UIScrollview 也不是我想要的设计,因为我想看到所有 40 行和后来的底部标签,我不想滚动表格视图,因为我想要scrollview 滚动顶部标签、所有行和底部标签(我想在那里添加更多东西)。

这些是约束:

为了简单起见,此时单元格是一个基本单元格,我知道以后我必须做一些额外的事情才能让 Autolayout 与动态单元格一起使用。

你能告诉我会发生什么吗

【问题讨论】:

  • UITableViewUIScrollView 的子类,所以您似乎正在尝试将滚动视图嵌入到另一个滚动视图中?
  • @Cristik 我知道,但我在 UITableView 中禁用了滚动视图。
  • 仍然,您尝试将滚动视图嵌入到滚动视图中,而不管您尝试对嵌入的设置进行什么设置。如果发生意外行为,请不要感到惊讶:)
  • 嵌套滚动视图本身并没有什么问题。几年前在 WWDC 上有一个非常简洁的视频,他们反复演示了使用嵌套的滚动视图来完成复杂的效果。
  • 顺便说一句,表格/部分页眉和页脚不会帮助您避免嵌入滚动视图的需要吗?

标签: ios swift uitableview uiscrollview autolayout


【解决方案1】:

您的评论“我的想法是将来在左侧添加一些超出滚动条的图标” 并没有任何意义。如果您想要非滚动图标,只需将它们放在表格视图之外。

将表格视图放在滚动视图中并非不可能……但是,您会失去可重用单元格的效率。

如果你有 40 个相对“重量轻”的电池,可能没什么大不了的。

但是假设你的细胞很“重”?例如,几个图像、控件、标签等?而且,假设您有 100 多个细胞?那么你就不必要地超载了内存使用。

但是,如果您真的想尝试您的方法,您可以像这样子类化UITableView

// non-scrolling table view that automatically sets its
//  intrinsicContentSize based on its cells
final class AutoHeightTableView: UITableView {
    
    override init(frame: CGRect, style: UITableView.Style) {
        super.init(frame: frame, style: style)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    
    func commonInit() -> Void {
        isScrollEnabled = false
        setContentCompressionResistancePriority(.required, for: .vertical)
    }
    
    override var contentSize: CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }
    
    override func reloadData() {
        super.reloadData()
        invalidateIntrinsicContentSize()
    }
    
    override var intrinsicContentSize: CGSize {
        setNeedsLayout()
        layoutIfNeeded()
        return contentSize
    }
    
}

现在,您的表格视图将更像一个多行标签,根据其内容设置其高度。

这是一个完整的例子:

class DashBoardViewController: UIViewController {

    @IBOutlet var autoHeightTableView: AutoHeightTableView!
    
    let sampleStrings: [String] = [
        "A sample string.",
        "Sample string with\ntwo rows.",
        "Sample string with enough text to cause word-wrapping.",
        "Sample string with enough text to cause word-wrapping, even if we have a very wide table (such as an iPhone in Landscape Orientation)."
    ]
    
    var numRows: Int = 1
    
    override func viewDidLoad() {
        super.viewDidLoad()

        autoHeightTableView.dataSource = self
        autoHeightTableView.delegate = self
        
        autoHeightTableView.register(SimpleCell.self, forCellReuseIdentifier: "cell")
    }
    
    @IBAction func addRowTapped(_ sender: Any) {
        // add a row
        numRows += 1
        autoHeightTableView.reloadData()
    }
    
    @IBAction func removeRowTapped(_ sender: Any) {
        // remove a row, but keep at least 1
        numRows -= 1
        numRows = max(1, numRows)
        autoHeightTableView.reloadData()
    }
    
}

extension DashBoardViewController: UITableViewDelegate, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return numRows
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let c = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SimpleCell
        let s = sampleStrings[indexPath.row % sampleStrings.count]
        c.theLabel.text = "Row \(indexPath.row) - \(s)"
        return c
    }
}

class SimpleCell: UITableViewCell {
    
    let theLabel: UILabel = {
        let v = UILabel()
        v.numberOfLines = 0
        return v
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() -> Void {
        theLabel.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(theLabel)
        let g = contentView.layoutMarginsGuide
        NSLayoutConstraint.activate([
            theLabel.topAnchor.constraint(equalTo: g.topAnchor),
            theLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor),
            theLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor),
            theLabel.bottomAnchor.constraint(equalTo: g.bottomAnchor),
        ])
        theLabel.backgroundColor = .yellow
    }
    
}

和一个与之一起使用的故事板:

<?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="2DO-DK-DvL">
    <device id="retina3_5" orientation="portrait" appearance="light"/>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
        <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>
        <!--Dash Board View Controller-->
        <scene sceneID="g75-XE-t5u">
            <objects>
                <viewController id="2DO-DK-DvL" customClass="DashBoardViewController" customModule="VeryTemp" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="O6N-jW-fEC">
                        <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SJM-7N-dTP" userLabel="ButtonView">
                                <rect key="frame" x="0.0" y="0.0" width="320" height="60"/>
                                <subviews>
                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aEu-IP-rXM">
                                        <rect key="frame" x="101" y="10" width="85" height="40"/>
                                        <color key="backgroundColor" red="1" green="0.49327188729999999" blue="0.47399842739999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <fontDescription key="fontDescription" type="system" pointSize="16"/>
                                        <inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
                                        <state key="normal" title="Add Row"/>
                                        <state key="highlighted">
                                            <color key="titleColor" red="0.83741801979999997" green="0.83743780850000005" blue="0.83742713930000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        </state>
                                        <connections>
                                            <action selector="addRowTapped:" destination="2DO-DK-DvL" eventType="touchUpInside" id="QCw-Z5-VC0"/>
                                        </connections>
                                    </button>
                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xrr-ve-UDf">
                                        <rect key="frame" x="196" y="10" width="114" height="40"/>
                                        <color key="backgroundColor" red="1" green="0.49327188729999999" blue="0.47399842739999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        <fontDescription key="fontDescription" type="system" pointSize="16"/>
                                        <inset key="contentEdgeInsets" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
                                        <state key="normal" title="Remove Row"/>
                                        <state key="highlighted">
                                            <color key="titleColor" red="0.83741801979999997" green="0.83743780850000005" blue="0.83742713930000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                        </state>
                                        <connections>
                                            <action selector="removeRowTapped:" destination="2DO-DK-DvL" eventType="touchUpInside" id="cZu-vf-pDE"/>
                                        </connections>
                                    </button>
                                </subviews>
                                <color key="backgroundColor" red="0.83741801979999997" green="0.83743780850000005" blue="0.83742713930000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="60" id="09y-jl-yti"/>
                                    <constraint firstAttribute="bottom" secondItem="xrr-ve-UDf" secondAttribute="bottom" constant="10" id="0Se-yT-hhY"/>
                                    <constraint firstItem="xrr-ve-UDf" firstAttribute="leading" secondItem="aEu-IP-rXM" secondAttribute="trailing" constant="10" id="Bf2-5m-rCJ"/>
                                    <constraint firstItem="aEu-IP-rXM" firstAttribute="top" secondItem="SJM-7N-dTP" secondAttribute="top" constant="10" id="YoS-xx-NXR"/>
                                    <constraint firstAttribute="trailing" secondItem="xrr-ve-UDf" secondAttribute="trailing" constant="10" id="ZN7-IA-HyF"/>
                                    <constraint firstItem="xrr-ve-UDf" firstAttribute="top" secondItem="SJM-7N-dTP" secondAttribute="top" constant="10" id="fOU-kX-dYl"/>
                                    <constraint firstAttribute="bottom" secondItem="aEu-IP-rXM" secondAttribute="bottom" constant="10" id="vKl-iB-du9"/>
                                </constraints>
                            </view>
                            <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5tP-7Y-LPu">
                                <rect key="frame" x="0.0" y="60" width="320" height="420"/>
                                <subviews>
                                    <view contentMode="scaleToFill" placeholderIntrinsicWidth="infinite" placeholderIntrinsicHeight="320" translatesAutoresizingMaskIntoConstraints="NO" id="rE3-Cv-Een" userLabel="ScrollContentView">
                                        <rect key="frame" x="0.0" y="0.0" width="320" height="320"/>
                                        <subviews>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Active" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WZM-qS-dOD">
                                                <rect key="frame" x="8" y="8" width="304" height="30"/>
                                                <color key="backgroundColor" systemColor="systemYellowColor"/>
                                                <constraints>
                                                    <constraint firstAttribute="height" constant="30" id="IMg-Wn-BgL"/>
                                                </constraints>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="f4v-Zc-2KD" customClass="AutoHeightTableView" customModule="VeryTemp" customModuleProvider="target">
                                                <rect key="frame" x="8" y="46" width="304" height="228"/>
                                                <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                                            </tableView>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Assigned" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HPf-Zx-zNZ">
                                                <rect key="frame" x="8" y="282" width="304" height="30"/>
                                                <color key="backgroundColor" red="0.0" green="0.97680455450000003" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <constraints>
                                                    <constraint firstAttribute="height" constant="30" id="yqD-Mj-ksF"/>
                                                </constraints>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                        </subviews>
                                        <color key="backgroundColor" systemColor="systemOrangeColor"/>
                                        <constraints>
                                            <constraint firstAttribute="bottom" secondItem="HPf-Zx-zNZ" secondAttribute="bottom" constant="8" id="140-cK-vKT"/>
                                            <constraint firstItem="HPf-Zx-zNZ" firstAttribute="top" secondItem="f4v-Zc-2KD" secondAttribute="bottom" constant="8" id="3yP-CX-WkR"/>
                                            <constraint firstAttribute="trailing" secondItem="HPf-Zx-zNZ" secondAttribute="trailing" constant="8" id="BoD-9D-w0x"/>
                                            <constraint firstAttribute="trailing" secondItem="WZM-qS-dOD" secondAttribute="trailing" constant="8" id="Gg5-xY-Cwl"/>
                                            <constraint firstItem="f4v-Zc-2KD" firstAttribute="top" secondItem="WZM-qS-dOD" secondAttribute="bottom" constant="8" id="KtX-GG-0hK"/>
                                            <constraint firstAttribute="trailing" secondItem="f4v-Zc-2KD" secondAttribute="trailing" constant="8" id="ZYI-Be-xwl"/>
                                            <constraint firstItem="WZM-qS-dOD" firstAttribute="top" secondItem="rE3-Cv-Een" secondAttribute="top" constant="8" id="gd8-b8-jns"/>
                                            <constraint firstItem="f4v-Zc-2KD" firstAttribute="leading" secondItem="rE3-Cv-Een" secondAttribute="leading" constant="8" id="jxB-sB-07D"/>
                                            <constraint firstItem="HPf-Zx-zNZ" firstAttribute="leading" secondItem="rE3-Cv-Een" secondAttribute="leading" constant="8" id="oIJ-Ck-Fn1"/>
                                            <constraint firstItem="WZM-qS-dOD" firstAttribute="leading" secondItem="rE3-Cv-Een" secondAttribute="leading" constant="8" id="sSz-2Y-Yg8"/>
                                        </constraints>
                                    </view>
                                </subviews>
                                <color key="backgroundColor" systemColor="systemBlueColor"/>
                                <constraints>
                                    <constraint firstItem="rE3-Cv-Een" firstAttribute="leading" secondItem="fnD-Eq-tO0" secondAttribute="leading" id="Qfc-ph-JoH"/>
                                    <constraint firstItem="rE3-Cv-Een" firstAttribute="trailing" secondItem="fnD-Eq-tO0" secondAttribute="trailing" id="XN9-8n-zw2"/>
                                    <constraint firstItem="rE3-Cv-Een" firstAttribute="top" secondItem="fnD-Eq-tO0" secondAttribute="top" id="ehk-so-dph"/>
                                    <constraint firstItem="rE3-Cv-Een" firstAttribute="width" secondItem="AzI-2g-Rnq" secondAttribute="width" id="jDq-Zz-Sxk"/>
                                    <constraint firstItem="rE3-Cv-Een" firstAttribute="bottom" secondItem="fnD-Eq-tO0" secondAttribute="bottom" id="sZW-ak-PM4"/>
                                </constraints>
                                <viewLayoutGuide key="contentLayoutGuide" id="fnD-Eq-tO0"/>
                                <viewLayoutGuide key="frameLayoutGuide" id="AzI-2g-Rnq"/>
                            </scrollView>
                        </subviews>
                        <viewLayoutGuide key="safeArea" id="od6-UL-Lpv"/>
                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                        <constraints>
                            <constraint firstItem="od6-UL-Lpv" firstAttribute="bottom" secondItem="5tP-7Y-LPu" secondAttribute="bottom" id="2dd-pa-B3b"/>
                            <constraint firstItem="SJM-7N-dTP" firstAttribute="top" secondItem="od6-UL-Lpv" secondAttribute="top" id="BrD-hB-LgN"/>
                            <constraint firstItem="od6-UL-Lpv" firstAttribute="trailing" secondItem="5tP-7Y-LPu" secondAttribute="trailing" id="LGO-eJ-Odx"/>
                            <constraint firstItem="5tP-7Y-LPu" firstAttribute="top" secondItem="SJM-7N-dTP" secondAttribute="bottom" id="ShA-aH-tNi"/>
                            <constraint firstItem="5tP-7Y-LPu" firstAttribute="leading" secondItem="od6-UL-Lpv" secondAttribute="leading" id="Y3a-Ku-y5C"/>
                            <constraint firstItem="SJM-7N-dTP" firstAttribute="leading" secondItem="od6-UL-Lpv" secondAttribute="leading" id="iPv-pY-elL"/>
                            <constraint firstItem="od6-UL-Lpv" firstAttribute="trailing" secondItem="SJM-7N-dTP" secondAttribute="trailing" id="owk-qt-e66"/>
                        </constraints>
                    </view>
                    <connections>
                        <outlet property="autoHeightTableView" destination="f4v-Zc-2KD" id="dUe-Q7-MBs"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iKW-xF-1vd" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="341.25" y="100"/>
        </scene>
    </scenes>
    <resources>
        <systemColor name="systemBackgroundColor">
            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
        </systemColor>
        <systemColor name="systemBlueColor">
            <color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
        <systemColor name="systemOrangeColor">
            <color red="1" green="0.58431372549019611" blue="0.0" 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>

【讨论】:

    猜你喜欢
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多