How to Make the Scroll of a Tableview Inside Scrollview Behave Naturally

How to Make TableView scroll inside ScrollView behave naturally

First, never put tableview inside a scrollview, it's a bad practice. You could just use tableview header and embed any type of view do you want before the tableview cells.

here's a snipeste on how I deal with it:

//MARK: ConfigureTableView
private func configureTableView(){
let footerView = UIView()
footerView.frame.size.height = 50
footerView.backgroundColor = .white
self.tableView.tableFooterView = footerView
self.tableView.tableHeaderView = self.headerView
var newFrame = headerView.frame

newFrame.size.width = view.bounds.width
newFrame.size.height = 300
headerView.frame = newFrame

tableView.backgroundView = UIView()
tableView.backgroundView?.addSubview(backgroundTableView)
}

as you can see, I embedded a UIView as a footer and another UIView named headerView as a header

but if you insist of using a tableview inside a scrollview, you can try using a scrollview delegate and detech which scrollview is scrolling


func scrollViewDidScroll(_ scrollView: UIScrollView) {
let yOffset = scrollView.contentOffset.y

if scrollView == self.scrollView {
if yOffset >= scrollViewContentHeight - screenHeight {
// logic when using scrollview
}
}

if scrollView == self.tableView {
if yOffset <= 0 {
// logic when using tableview scrollView
}
}

}

TableView inside ScrollView , How to calculate tableview height at runtime?

I understood your problem that you want to calculate dynamic table height with flexible cells height inside tableview and according to this height you want to update your parent scrollview contentSize height .

I want to tell you that please remove your all your height calculation and just place this below simple function in side your view controller.

IMPORTANT:- Don't give any Height Constraint to your table view if you are using AutoLayout from your storyboard or programatically.

kindly take care of your variable names of tableview and scrollview and replace them respectively .

   //MARK:- viewDidLayoutSubviews will call after dynamic height calculation automatically
override func viewDidLayoutSubviews() {

//isScrollEnabled of table view should be dissable because our table is inside scrollview.
tableView.isScrollEnabled = false


//if above tableView.contentSize.height not zero and giving acurate value then proceed further and update our parent scroll view contentsize height for height.
print(tableView.contentSize.height)



//place some bottom peeding as you want
let bottomPedding:CGFloat = 30


//Finally update your scrollview content size with newly created table height + bottom pedding.
scrollview.contentSize = CGSize.init(width: scrollview.contentSize.width, height:tableView.contentSize.height + bottomPedding)


}

if this will work then fantastic then great , rest you can contact me any time we will figure it out.
asrathoreforiphone@gmail.com

how to make a table view inside scroll view?

You can easily accomplish this by giving the table an initial height hook it to IB and change it according to number of rows as your images it seems it's static say 70 , you can look this layout , open Main.storyboard as source code and copy paste this XML

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<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="CustomTexF" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<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="gQl-vh-MlV">
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7JP-ij-rQ3">
<rect key="frame" x="0.0" y="0.0" width="375" height="650"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oNu-7X-37n">
<rect key="frame" x="0.0" y="0.0" width="375" height="200"/>
<color key="backgroundColor" red="1" green="0.49823676220000002" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
<constraint firstAttribute="height" constant="200" id="IR2-Tm-rye"/>
</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="ivs-Bl-FXa">
<rect key="frame" x="0.0" y="200" width="375" height="300"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="300" id="Jir-gH-kN4"/>
</constraints>
</tableView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Lma-pM-X0g">
<rect key="frame" x="0.0" y="500" width="375" height="150"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="150" id="1eR-tC-Mar"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="oNu-7X-37n" secondAttribute="trailing" id="IF5-Q4-Yyz"/>
<constraint firstItem="oNu-7X-37n" firstAttribute="leading" secondItem="7JP-ij-rQ3" secondAttribute="leading" id="L5c-9H-y57"/>
<constraint firstItem="ivs-Bl-FXa" firstAttribute="leading" secondItem="7JP-ij-rQ3" secondAttribute="leading" id="MTy-Go-8Nz"/>
<constraint firstAttribute="trailing" secondItem="ivs-Bl-FXa" secondAttribute="trailing" id="NBz-UU-WZr"/>
<constraint firstItem="ivs-Bl-FXa" firstAttribute="top" secondItem="oNu-7X-37n" secondAttribute="bottom" id="Sn8-9m-9HT"/>
<constraint firstItem="Lma-pM-X0g" firstAttribute="leading" secondItem="7JP-ij-rQ3" secondAttribute="leading" id="TSl-Yd-64k"/>
<constraint firstItem="Lma-pM-X0g" firstAttribute="top" secondItem="ivs-Bl-FXa" secondAttribute="bottom" id="eGZ-3R-Rey"/>
<constraint firstAttribute="bottom" secondItem="Lma-pM-X0g" secondAttribute="bottom" id="pef-k0-8nU"/>
<constraint firstItem="oNu-7X-37n" firstAttribute="top" secondItem="7JP-ij-rQ3" secondAttribute="top" id="qsE-OQ-4x6"/>
<constraint firstAttribute="trailing" secondItem="Lma-pM-X0g" secondAttribute="trailing" id="u4o-l3-56h"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="7JP-ij-rQ3" secondAttribute="bottom" priority="250" id="5Pl-Zc-jKy"/>
<constraint firstItem="7JP-ij-rQ3" firstAttribute="leading" secondItem="gQl-vh-MlV" secondAttribute="leading" id="6wk-HX-XUh"/>
<constraint firstAttribute="trailing" secondItem="7JP-ij-rQ3" secondAttribute="trailing" id="hSU-wA-1v0"/>
<constraint firstItem="7JP-ij-rQ3" firstAttribute="top" secondItem="gQl-vh-MlV" secondAttribute="top" id="o0p-fH-VhV"/>
<constraint firstItem="7JP-ij-rQ3" firstAttribute="width" secondItem="gQl-vh-MlV" secondAttribute="width" id="wgf-e8-HLU"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="gQl-vh-MlV" secondAttribute="bottom" id="Axy-dp-ZiJ"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="gQl-vh-MlV" secondAttribute="trailing" id="LED-nS-Ba6"/>
<constraint firstItem="gQl-vh-MlV" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" id="RS2-MF-Aya"/>
<constraint firstItem="gQl-vh-MlV" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="euc-Qn-E0q"/>
</constraints>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

//

 tableViewHeightConstraint.constant = 100 * 70 
self.view.layoutIfNeeded()

and implement this method

func tableView(_ tableView: UITableView, 
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70 // height for every row
}

I want a UITableView inside of a UIScrollView to extend to the bottom of the UIScrollView and not get cut off by initial screen

I suggest you to use tableView only. You can create your top view in the header of tableView. Doing this there will be no need to maintain the content size of scrollView.



Related Topics



Leave a reply



Submit