Swift: change tableview height on scroll
Solution 1
I haven't tested it but you can do this. Use Autolayout in this view. it will work better with that.
Set the tableview constraint as Top, Left, Bottom, Right => 0, 0, 0, 0 with the main view and put collectionView under the tableview with constraint as Top,Left,Right, height => 0, 0, 0, x with the main view.
Note: Tableview is on top of the collectionView.
Connect your height constraint outlet of CollectionView and also define your defaultOffset variable
@IBOutlet weak var defaultHeightConstraint: NSLayoutConstraint
var defaultOffSet: CGPoint?
In viewDidLoad,
override func viewDidLoad() {
super.viewDidLoad()
tableView.contentInset = UIEdgeInsetsMake(collectionView.size.height, 0, 0, 0)
}
In viewDidAppear, write
override func viewDidAppear(_ animated: Bool) {
defaultOffSet = tableView.contentOffset
}
In ViewDidScroll
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = tableView.contentOffset
if let startOffset = self.defaultOffSet {
if offset.y < startOffset.y {
// Scrolling down
// check if your collection view height is less than normal height, do your logic.
let deltaY = fabs((startOffset.y - offset.y))
defaultHeightConstraint.constant = defaultHeightConstraint.constant - deltaY
} else {
// Scrolling up
let deltaY = fabs((startOffset.y - offset.y))
defaultHeightConstraint.constant = defaultHeightConstraint.constant + deltaY
}
self.view.layoutIfNeeded()
}
}
Hope it helps.
Solution 2
Since UITableView
is a subclass of UIScrollView
, your table view's delegate
can receive UIScrollViewDelegate
methods.
You don't need to use PanGesture
First implement UITableviewDelegate
and in that
var oldContentOffset = CGPoint.zero
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let contentOffset = scrollView.contentOffset.y - oldContentOffset.y
if (self.oldContentOffset < scrollView.contentOffset.y) {
// moved to top
} else if (self.oldContentOffset > scrollView.contentOffset.y) {
// moved to bottom
} else {
// didn't move
}
oldContentOffset = scrollView.contentOffset
}
Here you can write you logic to change constant value of your constraint
UPDATE/EDIT
Another thing is don't use multiplier for tabelview height.with collection view it is fine you can give height constraint with self.view in ratio of 1/3 . for tableview just give leading ,trailing top (UICollectionView) and bottom. So when you change height constant of UICollectionView Tableview height automatically decrease and vice-versa for decrease.
You can not change the multiplier from the outlet as it is read only. so you have to constant value to self.view.frame.height / 3
will work for you
Hope it is helpful to you
Aryan Sharma
Been writing code since '07. Started from VB now I'm here(Swift). Love to make apps with a superb UX. Love for animations. A firm believer of the fact that 'Looks Matter'. A beautifully designed app will surely sell. Proficiency in iOS Development. Good understanding of Firebase, Google Cloud functions(NodeJS). Handled complete technology wing of a startup for more than 10 months. From backend to frontend, handled everything. Now working as the Lead Engineer at Smartsense.
Updated on June 04, 2022Comments
-
Aryan Sharma almost 2 years
I have a VC as shown in the image
It has a UICollectionView on top, and a UITableView at the bottom. CollectionView has 1:3 of the screen and TableView has 2:3 of the screen(set using equalHeight constraint).
I want to change the height of the UICollectionView when the tableView is scrolled.
When the tableView is scrolled up,I want to change the multiplier of equalHeights constraint to like 1:5 and 4:5 of collectionView and tableView respectively.This will ensure that height of tableView increases and collectionView decreases
When the tableView is scrolled down, the multiplier of equalHeights constraint should reset to default.
I've tried adding swipe and pan gestures to tableView, but they are unrecognised.
How to achieve this functionality?
P.S: Would love to achieve this functionality by using a pan gesture, so that dragging up and down changes the heights progressively.
EDIT/UPDATE
This is the code that I'm using.
class MyConstant { var height:CGFloat = 10 } let myConstant = MyConstant()
MainScreenVC
override func viewWillAppear(_ animated: Bool) { myConstant.height = self.view.frame.size.height } func scrollViewDidScroll(_ scrollView: UIScrollView) { if (self.lastContentOffset < scrollView.contentOffset.y) { NotificationCenter.default.post(name: Notifications.decreaseHeightNotification.name, object: nil) self.topViewConstraint.constant = -self.view.frame.height / 6 UIView.animate(withDuration: 0.3, animations: { self.view.layoutIfNeeded() }) } else if (self.lastContentOffset > scrollView.contentOffset.y) { NotificationCenter.default.post(name: Notifications.increaseHeightNotification.name, object: nil) self.topViewConstraint.constant = 0 UIView.animate(withDuration: 0.3, animations: { self.view.layoutIfNeeded() }) } self.lastContentOffset = scrollView.contentOffset.y }
Cell.Swift
override func awakeFromNib() { super.awakeFromNib() NotificationCenter.default.addObserver(self, selector: #selector(decreaseHeight), name: Notification.Name("decreaseHeightNotification"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(increaseHeight), name: Notification.Name("increaseHeightNotification"), object: nil) self.contentView.translatesAutoresizingMaskIntoConstraints = false heightConstraint.constant = (myConstant.height / 3) - 10 widthConstraint.constant = heightConstraint.constant * 1.5 } @objc func decreaseHeight() { heightConstraint.constant = (myConstant.height / 6) - 10 widthConstraint.constant = (heightConstraint.constant * 1.5) self.layoutIfNeeded() } @objc func increaseHeight() { heightConstraint.constant = (myConstant.height / 3) - 10 widthConstraint.constant = (heightConstraint.constant * 1.5) self.layoutIfNeeded() }
Now when I scroll both simultaneously, the screen freezes. Also is there a better way of resizing the collectionViewCell size?
-
nothingwhatsoever over 6 yearsCan you post your code snippet here? This question is incomplete without the approach you are using. Once that is available, you can expect relevant answers.
-
Aryan Sharma over 6 years@nothingwhatsoever check it out
-
Prashant Tukadiya over 6 yearsWhy you are increasing height of your content view ?. it should be leading, trailing , top , bottom with cell so it will automatically increase height as per cell. after scroll on tableview instead of posting notification use collection view invalidate for this see this aplus.rs/2015/… .What are you doing in your height for item at Indexpath.
-
-
Aryan Sharma over 6 yearsSo according to you, for collectionView: use multiplier with 1:3 value. For tableView: add top, bottom, left and right constraints. top being relative to collection view. On scroll: change only multiplier value so everything adjusts automatically?
-
Prashant Tukadiya over 6 years@AryanSharma yes !! , You just have to change height of collection view . since tableview top == collectionview.bottom so tableview automatically adjust as per collection view height changes !! . And you can not change multiplier value you have to change constat value :)