如何在Swift中使用两个TableView设计动态布局 [英] How to design a dynamic layout with two TableViews in Swift

查看:126
本文介绍了如何在Swift中使用两个TableView设计动态布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

程序员.

我花了很多时间试图在Swift中设计这种布局,但收效甚微.

I've spent many hours trying to design this layout in Swift, with little success.

布局图

这个想法是有两个TableViews:

The idea is having two TableViews:

  • 最上面的一个,具有零个或多个(不确定的)单元格,这些单元格不可滚动,并且其高度随着单元格的数量而增加.
  • 底部的一个具有零个或多个(不确定的)单元格,该单元格是可滚动的,因此其高度适应于后一个表格视图剩下的空间.

我已经尝试通过编程方式来处理约束,方法是将两个表的top约束都设置到屏幕顶部,然后根据top TableView的大小修改该约束.似乎不起作用.

I've already tried to play with the constraints programmatically, by setting both tables top constraint to the top of the screen and then modifying that constraint depending on the size of the top TableView. Doesn't seem to work.

我还尝试根据要绘制的单元格的数量,以编程方式修改表格的高度.也没用.

I also tried to modify the height of the tables programmatically, based on the number of cells that will be draw. Didn't work either.

老实说,我现在正处于一个死点,我正在寻找帮助或一些新想法来使它工作.任何帮助将不胜感激.预先感谢!

Honestly, I'm at a deadpoint right now, and I'm looking out for help or some new ideas to make it work. Any help will be highly appreciated. Thanks in advance!

推荐答案

您需要确定一些其他逻辑-例如,当顶表视图中的行太多时该怎么做,但这是一个方法:

You'll need to decide on some additional logic - as in, what to do when there are too many rows in the top table view, but this is one approach:

使用此自定义表格视图类(来自 https://stackoverflow.com/a/48623673/6257435 ):

Use this custom table view class (from https://stackoverflow.com/a/48623673/6257435):

final class ContentSizedTableView: UITableView {
    override var contentSize:CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }
}

每当内容大小更改时,这将自动调整大小"您的表视图.要使用它,请添加一个表视图并将其类设置为ContentSizedTableView.

This will "auto-size" your table view whenever the content size changes. To use it, add a table view and set its class to ContentSizedTableView.

  • 根据需要约束顶部,前导和尾随.
  • 将底部限制为底部表格视图的顶部.
  • 赋予高度限制-并不重要,但是使用200可以处理布局.但是...编辑该高度限制并选中占位符-在构建时删除复选框.
  • 根据需要将底部表格视图限制为开头,结尾和底部.
  • Constrain the top, leading and trailing as desired.
  • Constrain the bottom to the top of the bottom table view.
  • Give it a height constraint - doesn't really matter what, but using 200 let's you work with the layout. But... edit that height constraint and check the Placeholder - Remove at build time checkbox.
  • Constrain the bottom table view to leading, trailing and bottom as desired.

现在,当您在top table view中添加行时,它将自动垂直扩展,而bottom table view将垂直自动收缩(直到消失).由于top table view底部仍然限制在bottom table view top 上,因此top table view将停止增长并且可以滚动(而不是扩展到视图的底部).

Now, when you add rows to the top table view, it will auto-expand vertically, and the bottom table view will auto-contract vertically (until it disappears). Because the bottom of the top table view is still constrained to the top of the bottom table view, the top table view will stop growing and be scrollable (instead of extending off the bottom of the view).

这是一个非常简单的示例:

Here's a very simple example:

import UIKit

final class ContentSizedTableView: UITableView {
    override var contentSize:CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }

    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }
}

class SimpleTopCell: UITableViewCell {

    @IBOutlet var theLabel: UILabel!

}

class SimpleBottomCell: UITableViewCell {

    @IBOutlet var theLabel: UILabel!

}


class AutoSizeTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet var topTableView: ContentSizedTableView!

    @IBOutlet var bottomTableView: UITableView!

    var numRowsTop = 8
    var numRowsBottom = 12

    override func viewDidLoad() {
        super.viewDidLoad()

        topTableView.dataSource = self
        bottomTableView.dataSource = self

        topTableView.delegate = self
        bottomTableView.delegate = self

    }

    @IBAction func addRowTapped(_ sender: Any) {
        numRowsTop += 1
        topTableView.reloadData()
    }

    @IBAction func delRowTapped(_ sender: Any) {
        numRowsTop -= 1
        // make sure it's at least 1
        numRowsTop = max(numRowsTop, 1)
        topTableView.reloadData()
    }

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == topTableView {
            return numRowsTop
        }
        return numRowsBottom
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if tableView == topTableView {
            let cell = tableView.dequeueReusableCell(withIdentifier: "SimpleTopCell", for: indexPath) as! SimpleTopCell
            cell.theLabel.text = "Top: \(indexPath)"
            return cell
        }
        let cell = tableView.dequeueReusableCell(withIdentifier: "SimpleBottomCell", for: indexPath) as! SimpleBottomCell
        cell.theLabel.text = "Bottom: \(indexPath)"
        return cell
    }

}

顶部有8行,底部有12行,我们得到:

With 8 rows in the top, and 12 rows in the bottom, we get:

,顶部有11行:

最后是顶部的17行(滚动显示,您可以看到):

and finally with 17 rows in the top (scrolled so you can see):

以下是该示例的情节提要源:

Here is the storyboard source for that example:

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Qun-XE-Shi">
    <device id="retina4_7" orientation="portrait">
        <adaptation id="fullscreen"/>
    </device>
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--Auto Size Table View Controller-->
        <scene sceneID="fo7-Cf-tO5">
            <objects>
                <viewController id="Qun-XE-Shi" customClass="AutoSizeTableViewController" customModule="XC10SWScratch" customModuleProvider="target" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="Vvb-uu-phq">
                        <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" distribution="fillEqually" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="uEB-QI-6Jy">
                                <rect key="frame" x="87.5" y="44" width="200" height="30"/>
                                <subviews>
                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qaz-hh-38L">
                                        <rect key="frame" x="0.0" y="0.0" width="85" height="30"/>
                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        <state key="normal" title="Add Row"/>
                                        <connections>
                                            <action selector="addRowTapped:" destination="Qun-XE-Shi" eventType="touchUpInside" id="01O-ew-Ezw"/>
                                        </connections>
                                    </button>
                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aEk-df-qAr">
                                        <rect key="frame" x="115" y="0.0" width="85" height="30"/>
                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                        <state key="normal" title="Del Row"/>
                                        <connections>
                                            <action selector="delRowTapped:" destination="Qun-XE-Shi" eventType="touchUpInside" id="qXr-S1-utk"/>
                                        </connections>
                                    </button>
                                </subviews>
                                <constraints>
                                    <constraint firstAttribute="width" constant="200" id="zau-ia-umI"/>
                                </constraints>
                            </stackView>
                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="2Kp-ZU-yGW" customClass="ContentSizedTableView" customModule="XC10SWScratch" customModuleProvider="target">
                                <rect key="frame" x="40" y="100" width="295" height="240"/>
                                <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="240" placeholder="YES" id="BHc-OJ-3pa"/>
                                </constraints>
                                <prototypes>
                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SimpleTopCell" id="TcM-H4-6wf" customClass="SimpleTopCell" customModule="XC10SWScratch" customModuleProvider="target">
                                        <rect key="frame" x="0.0" y="28" width="295" height="44"/>
                                        <autoresizingMask key="autoresizingMask"/>
                                        <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TcM-H4-6wf" id="Zvz-a3-fip">
                                            <rect key="frame" x="0.0" y="0.0" width="295" height="43.5"/>
                                            <autoresizingMask key="autoresizingMask"/>
                                            <subviews>
                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VZP-Nh-tor">
                                                    <rect key="frame" x="15" y="11" width="265" height="22"/>
                                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                    <nil key="textColor"/>
                                                    <nil key="highlightedColor"/>
                                                </label>
                                            </subviews>
                                            <constraints>
                                                <constraint firstItem="VZP-Nh-tor" firstAttribute="top" secondItem="Zvz-a3-fip" secondAttribute="topMargin" id="0CD-yt-vZ5"/>
                                                <constraint firstItem="VZP-Nh-tor" firstAttribute="leading" secondItem="Zvz-a3-fip" secondAttribute="leadingMargin" id="7LB-3U-q99"/>
                                                <constraint firstAttribute="trailingMargin" secondItem="VZP-Nh-tor" secondAttribute="trailing" id="Pp4-PA-tvk"/>
                                                <constraint firstItem="VZP-Nh-tor" firstAttribute="bottom" secondItem="Zvz-a3-fip" secondAttribute="bottomMargin" id="xP2-ad-aPi"/>
                                            </constraints>
                                        </tableViewCellContentView>
                                        <connections>
                                            <outlet property="theLabel" destination="VZP-Nh-tor" id="aiq-L8-DYT"/>
                                        </connections>
                                    </tableViewCell>
                                </prototypes>
                            </tableView>
                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="UCl-gz-0HT">
                                <rect key="frame" x="40" y="360" width="295" height="287"/>
                                <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                <prototypes>
                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="SimpleBottomCell" id="PtI-n4-c5u" customClass="SimpleBottomCell" customModule="XC10SWScratch" customModuleProvider="target">
                                        <rect key="frame" x="0.0" y="28" width="295" height="44"/>
                                        <autoresizingMask key="autoresizingMask"/>
                                        <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="PtI-n4-c5u" id="bCo-w1-VQ7">
                                            <rect key="frame" x="0.0" y="0.0" width="295" height="43.5"/>
                                            <autoresizingMask key="autoresizingMask"/>
                                            <subviews>
                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Inu-NF-CgL">
                                                    <rect key="frame" x="15" y="11" width="265" height="22"/>
                                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                    <nil key="textColor"/>
                                                    <nil key="highlightedColor"/>
                                                </label>
                                            </subviews>
                                            <constraints>
                                                <constraint firstItem="Inu-NF-CgL" firstAttribute="bottom" secondItem="bCo-w1-VQ7" secondAttribute="bottomMargin" id="2Nz-Y2-ceX"/>
                                                <constraint firstItem="Inu-NF-CgL" firstAttribute="leading" secondItem="bCo-w1-VQ7" secondAttribute="leadingMargin" id="HIx-hC-b4c"/>
                                                <constraint firstItem="Inu-NF-CgL" firstAttribute="top" secondItem="bCo-w1-VQ7" secondAttribute="topMargin" id="Xfn-2l-Dyw"/>
                                                <constraint firstAttribute="trailingMargin" secondItem="Inu-NF-CgL" secondAttribute="trailing" id="f8F-YZ-jJh"/>
                                            </constraints>
                                        </tableViewCellContentView>
                                        <connections>
                                            <outlet property="theLabel" destination="Inu-NF-CgL" id="fsi-1C-DCU"/>
                                        </connections>
                                    </tableViewCell>
                                </prototypes>
                            </tableView>
                        </subviews>
                        <color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="UCl-gz-0HT" firstAttribute="top" secondItem="2Kp-ZU-yGW" secondAttribute="bottom" constant="20" id="2Kx-3i-Hd9"/>
                            <constraint firstItem="PTh-mY-2F7" firstAttribute="bottom" secondItem="UCl-gz-0HT" secondAttribute="bottom" constant="20" id="D50-Uk-fN0"/>
                            <constraint firstItem="PTh-mY-2F7" firstAttribute="trailing" secondItem="2Kp-ZU-yGW" secondAttribute="trailing" constant="40" id="F1H-8j-bVy"/>
                            <constraint firstItem="PTh-mY-2F7" firstAttribute="trailing" secondItem="UCl-gz-0HT" secondAttribute="trailing" constant="40" id="KXW-yh-GAA"/>
                            <constraint firstItem="uEB-QI-6Jy" firstAttribute="top" secondItem="PTh-mY-2F7" secondAttribute="top" constant="24" id="M5V-JO-Jfw"/>
                            <constraint firstItem="uEB-QI-6Jy" firstAttribute="centerX" secondItem="Vvb-uu-phq" secondAttribute="centerX" id="TlF-gf-jKf"/>
                            <constraint firstItem="2Kp-ZU-yGW" firstAttribute="top" secondItem="PTh-mY-2F7" secondAttribute="top" constant="80" id="XFo-ry-u9Y"/>
                            <constraint firstItem="2Kp-ZU-yGW" firstAttribute="leading" secondItem="PTh-mY-2F7" secondAttribute="leading" constant="40" id="iu7-sU-Gki"/>
                            <constraint firstItem="UCl-gz-0HT" firstAttribute="leading" secondItem="PTh-mY-2F7" secondAttribute="leading" constant="40" id="ni9-df-1kD"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="PTh-mY-2F7"/>
                    </view>
                    <navigationItem key="navigationItem" id="6mN-ug-bQV"/>
                    <connections>
                        <outlet property="bottomTableView" destination="UCl-gz-0HT" id="Yny-Gc-zhG"/>
                        <outlet property="topTableView" destination="2Kp-ZU-yGW" id="puB-6Z-xMa"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="kps-Ns-Nci" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="1088.8" y="2196.2518740629689"/>
        </scene>
    </scenes>
</document>

这篇关于如何在Swift中使用两个TableView设计动态布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆