contentView with UITableView not scrolling within UIScrollView(带有 UITableView 的 contentView 不在 UIScrollView 内滚动)
问题描述
I'm creating a simple "Create your Profile" with many fields. My view is not scrolling despite the content being larger than the size of the scroll view. I think part of the issue is the relationship between the contents inside the contentView. I wanted the cells inside of the table view to be dynamic so that I can add more information later and the scrolling would still preform. I set the scrollView delegate and tableView delegate to self in viewDidLoad()
I've looked at other answers and tried their implementations to no avail. I referenced Height of contentView of UIScrollView based on inside content using Storyboard, for instance.
To adjust the table view's content dynamically, I wrote the following:
override func viewDidLayoutSubviews() {
DispatchQueue.main.async {
var frame = self.tableView.frame
frame.size.height = self.tableView.contentSize.height
self.tableView.frame = frame
self.updateViewConstraints()
}
}
For constraints, my hierarchy is Super View > Scroll View > Content View > Elements.
Essentially, each element depends on it's upper neighbor and each have set heights. The exception is the TableView, whose height is not fixed, and will be stretched according to it's neighbor below it, the error label. The error label is then constrained to the bottom of the view. Here is a more visual representation.
Here is the actual result:
I think the issue is the Error Label's constraint to the Table View is not being updated, but is there something I'm not seeing here? Everything below the top bar should scroll.
Here is a basic example, using a "self-sizing" table view. No need for heightForRowAt
or explicit setting of .contentSize
-- it's all handled by auto-layout and constraints.
With a couple rows (nothing scrolls):
With a couple more rows (still, nothing scrolls):
And now with enough rows the we need scrolling:
This is how it's setup in IB / Storyboard:
Here is the source code:
//
// DaveViewController.swift
//
// Created by Don Mag on 7/1/19.
//
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 DaveCell: UITableViewCell {
@IBOutlet var theLabel: UILabel!
@IBOutlet var theTextField: UITextField!
}
class DaveViewController: UIViewController {
@IBOutlet var theTableView: ContentSizedTableView!
@IBOutlet var theScrollView: UIScrollView!
let theLabels: [String] = [
"NAME",
"COMPANY",
"POSITION",
"CITY, STATE",
"EMAIL ADDRESS",
"ADDTL EMAIL
ADDRESS",
"WORK NUMBER",
"CELL NUMBER",
]
let thePlaceholders: [String] = [
"your name",
"e.g. Bizee Inc.",
"e.g. Regional Manager",
"e.g. Denver, Colorado",
"name@email.com",
"name@email.com",
"(XXX) XXX-XXXX",
"(XXX) XXX-XXXX",
]
override func viewDidLoad() {
super.viewDidLoad()
theTableView.dataSource = self
theTableView.delegate = self
theTableView.isScrollEnabled = false
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
// add a "Done" button to dismiss the keyboard
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneTapped))
self.navigationItem.rightBarButtonItem = doneBtn
}
@objc private func doneTapped() {
view.endEditing(true)
}
@objc private func keyboardWillShow(notification: NSNotification){
guard let keyboardFrame = notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
theScrollView.contentInset.bottom = view.convert(keyboardFrame.cgRectValue, from: nil).size.height
}
@objc private func keyboardWillHide(notification: NSNotification){
theScrollView.contentInset.bottom = 0
}
}
extension DaveViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return theLabels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DaveCell", for: indexPath) as! DaveCell
cell.theLabel.text = theLabels[indexPath.row]
cell.theTextField.placeholder = thePlaceholders[indexPath.row]
cell.selectionStyle = .none
return cell
}
}
and here is the Storyboard source:
<?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="OCG-fk-O07">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<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>
<!--Dave View Controller-->
<scene sceneID="gYy-6C-lIo">
<objects>
<viewController id="ByF-jo-q34" customClass="DaveViewController" customModule="LaunchTest2" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="KzY-ir-ZNp">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sfU-bN-guh">
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SCY-zE-Vif">
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Import Using LinkedIn" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kg2-26-RDd">
<rect key="frame" x="104" y="12" width="167.5" height="20.5"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d56-0u-ihe">
<rect key="frame" x="0.0" y="44.5" width="375" height="102.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Choose Profile Photo" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8zb-Kb-NJY">
<rect key="frame" x="108" y="20" width="159.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" weight="thin" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="KiU-vK-XXr">
<rect key="frame" x="12" y="50.5" width="351" height="32"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7Ri-fC-xIB">
<rect key="frame" x="0.0" y="0.0" width="172.5" height="32"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" weight="thin" pointSize="16"/>
<state key="normal" title="Use Camera">
<color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RYr-md-Xbc">
<rect key="frame" x="178.5" y="0.0" width="172.5" height="32"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" weight="thin" pointSize="16"/>
<state key="normal" title="Use Photo Library">
<color key="titleColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
</subviews>
</stackView>
</subviews>
<color key="backgroundColor" red="0.91764705882352937" green="0.91764705882352937" blue="0.91764705882352937" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="8zb-Kb-NJY" firstAttribute="centerX" secondItem="d56-0u-ihe" secondAttribute="centerX" id="Ipm-mu-u52"/>
<constraint firstAttribute="trailing" secondItem="KiU-vK-XXr" secondAttribute="trailing" constant="12" id="M6p-kS-2Wj"/>
<constraint firstItem="8zb-Kb-NJY" firstAttribute="top" secondItem="d56-0u-ihe" secondAttribute="top" constant="20" id="R3e-cc-Fer"/>
<constraint firstAttribute="bottom" secondItem="KiU-vK-XXr" secondAttribute="bottom" constant="20" id="gX4-Zs-QVl"/>
<constraint firstItem="KiU-vK-XXr" firstAttribute="top" secondItem="8zb-Kb-NJY" secondAttribute="bottom" constant="10" id="inN-ct-lOI"/>
<constraint firstItem="KiU-vK-XXr" firstAttribute="leading" secondItem="d56-0u-ihe" secondAttribute="leading" constant="12" id="sFN-WJ-e2x"/>
</constraints>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="lnj-TZ-tdQ" customClass="ContentSizedTableView" customModule="LaunchTest2" customModuleProvider="target">
<rect key="frame" x="20" y="159" width="335" height="160"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" priority="250" constant="160" id="OWa-SK-1bb"/>
</constraints>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="DaveCell" rowHeight="67" id="UZ0-mW-z3R" customClass="DaveCell" customModule="LaunchTest2" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="335" height="67"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="UZ0-mW-z3R" id="Bpu-ZK-jmH">
<rect key="frame" x="0.0" y="0.0" width="335" height="66.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cta-dh-NKD">
<rect key="frame" x="15" y="23" width="42" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="right" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="CgS-ib-w4y">
<rect key="frame" x="69" y="18.5" width="251" height="30"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits"/>
</textField>
</subviews>
<constraints>
<constraint firstItem="cta-dh-NKD" firstAttribute="top" secondItem="Bpu-ZK-jmH" secondAttribute="topMargin" constant="12" id="We1-kz-q2C"/>
<constraint firstAttribute="bottomMargin" secondItem="cta-dh-NKD" secondAttribute="bottom" constant="12" id="Xrk-31-tpM"/>
<constraint firstItem="cta-dh-NKD" firstAttribute="leading" secondItem="Bpu-ZK-jmH" secondAttribute="leadingMargin" id="gWG-0p-rAe"/>
<constraint firstItem="CgS-ib-w4y" firstAttribute="centerY" secondItem="Bpu-ZK-jmH" secondAttribute="centerY" id="lQV-0f-plQ"/>
<constraint firstItem="CgS-ib-w4y" firstAttribute="leading" secondItem="cta-dh-NKD" secondAttribute="trailing" constant="12" id="t9H-NP-Nun"/>
<constraint firstAttribute="trailingMargin" secondItem="CgS-ib-w4y" secondAttribute="trailing" id="zfb-h1-T31"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="theLabel" destination="cta-dh-NKD" id="E47-0o-OD8"/>
<outlet property="theTextField" destination="CgS-ib-w4y" id="pNN-td-M2T"/>
</connections>
</tableViewCell>
</prototypes>
</tableView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Please put in a profile photo." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rAu-zB-NyR">
<rect key="frame" x="74.5" y="573.5" width="226.5" height="21.5"/>
<color key="backgroundColor" red="1" green="0.14913141730000001" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" weight="thin" pointSize="18"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="kg2-26-RDd" firstAttribute="top" secondItem="SCY-zE-Vif" secondAttribute="top" constant="12" id="80C-f1-Inf"/>
<constraint firstItem="rAu-zB-NyR" firstAttribute="top" relation="greaterThanOrEqual" secondItem="lnj-TZ-tdQ" secondAttribute="bottom" constant="8" id="9Sg-Aa-wir"/>
<constraint firstItem="lnj-TZ-tdQ" firstAttribute="top" secondItem="d56-0u-ihe" secondAttribute="bottom" constant="12" id="EhF-Gu-8vx"/>
<constraint firstAttribute="trailing" secondItem="d56-0u-ihe" secondAttribute="trailing" id="NuV-lh-WRd"/>
<constraint firstItem="d56-0u-ihe" firstAttribute="top" secondItem="kg2-26-RDd" secondAttribute="bottom" constant="12" id="Ppo-X8-gdk"/>
<constraint firstItem="lnj-TZ-tdQ" firstAttribute="leading" secondItem="SCY-zE-Vif" secondAttribute="leading" constant="20" id="QBd-ca-Itt"/>
<constraint firstItem="kg2-26-RDd" firstAttribute="centerX" secondItem="SCY-zE-Vif" secondAttribute="centerX" id="TLP-ZG-cWf"/>
<constraint firstItem="rAu-zB-NyR" firstAttribute="centerX" secondItem="SCY-zE-Vif" secondAttribute="centerX" id="Zat-D4-CeV"/>
<constraint firstAttribute="bottom" secondItem="rAu-zB-NyR" secondAttribute="bottom" constant="8" id="jdI-I6-eub"/>
<constraint firstAttribute="trailing" secondItem="lnj-TZ-tdQ" secondAttribute="trailing" constant="20" id="qls-uL-RxI"/>
<constraint firstItem="d56-0u-ihe" firstAttribute="leading" secondItem="SCY-zE-Vif" secondAttribute="leading" id="yBB-ls-1fU"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.99942404029999998" green="0.98555368190000003" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="SCY-zE-Vif" firstAttribute="width" secondItem="sfU-bN-guh" secondAttribute="width" id="0AS-Bw-vgM"/>
<constraint firstItem="SCY-zE-Vif" firstAttribute="height" secondItem="sfU-bN-guh" secondAttribute="height" priority="250" id="1nY-0L-LLo"/>
<constraint firstItem="SCY-zE-Vif" firstAttribute="top" secondItem="sfU-bN-guh" secondAttribute="top" id="Rqy-JP-jge"/>
<constraint firstAttribute="bottom" secondItem="SCY-zE-Vif" secondAttribute="bottom" id="S3L-Zg-fgS"/>
<constraint firstItem="SCY-zE-Vif" firstAttribute="leading" secondItem="sfU-bN-guh" secondAttribute="leading" id="fON-cd-chM"/>
<constraint firstAttribute="trailing" secondItem="SCY-zE-Vif" secondAttribute="trailing" id="vYb-7j-GxU"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="6HN-hq-UwM" firstAttribute="bottom" secondItem="sfU-bN-guh" secondAttribute="bottom" id="1QS-4N-gEW"/>
<constraint firstItem="sfU-bN-guh" firstAttribute="leading" secondItem="6HN-hq-UwM" secondAttribute="leading" id="5Ur-Gf-8pP"/>
<constraint firstItem="sfU-bN-guh" firstAttribute="top" secondItem="6HN-hq-UwM" secondAttribute="top" id="7DE-le-6vP"/>
<constraint firstItem="6HN-hq-UwM" firstAttribute="trailing" secondItem="sfU-bN-guh" secondAttribute="trailing" id="N4k-MG-Uef"/>
</constraints>
<viewLayoutGuide key="safeArea" id="6HN-hq-UwM"/>
</view>
<navigationItem key="navigationItem" id="Wwb-5l-bvB"/>
<connections>
<outlet property="theScrollView" destination="sfU-bN-guh" id="Mtz-hh-9i3"/>
<outlet property="theTableView" destination="lnj-TZ-tdQ" id="Rqn-pk-icA"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="mX1-qt-jnP" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="928.79999999999995" y="132.68365817091455"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="1J1-9A-mRF">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="OCG-fk-O07" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="RAe-Db-aHt">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="ByF-jo-q34" kind="relationship" relationship="rootViewController" id="9V8-EB-duR"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Asf-IX-RlV" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-10.4" y="132.68365817091455"/>
</scene>
</scenes>
</document>
这篇关于带有 UITableView 的 contentView 不在 UIScrollView 内滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:带有 UITableView 的 contentView 不在 UIScrollView 内滚动


- 使用自定义动画时在 iOS9 上忽略 edgesForExtendedLayout 2022-01-01
- 如何检查发送到 Android 应用程序的 Firebase 消息的传递状态? 2022-01-01
- MalformedJsonException:在第1行第1列路径中使用JsonReader.setLenient(True)接受格式错误的JSON 2022-01-01
- 想使用ViewPager,无法识别android.support.*? 2022-01-01
- Android viewpager检测滑动超出范围 2022-01-01
- Android - 拆分 Drawable 2022-01-01
- Android - 我如何找出用户有多少未读电子邮件? 2022-01-01
- android 4中的android RadioButton问题 2022-01-01
- 在测试浓缩咖啡时,Android设备不会在屏幕上启动活动 2022-01-01
- 用 Swift 实现 UITextFieldDelegate 2022-01-01