Collapse/Expand HeaderView With Tabs Part 2
In the previous part
https://medium.com/@yusefnaser93_79870/collapse-expand-headerview-with-tabs-part1-3fbad61d9028
We created Collapse/Expand header with two tabs
In this article, we will see some cases with bugs and how to solve it.
Let’s get started:
Case 1:
in the first tab, if scroll to bottom and go to the second tab, then scroll to top then return to the first tab and try to scroll to top
you can see the height of the header is changed like this:
We can solve this problem by set contentOffSet of scrollView to zero when trying to select the cell
in the function “cellForItemAt” for cell CellScrollView add this code
cell.scrollView.setContentOffset(.zero , animated: false )
and for cell CellTableView add this code
cell.tableView.setContentOffset(.zero , animated: false )
Now you can see when selecting every cell, scrollView start from the top and that is it 🤩🥳
Case 2:
If you remove second, third, fourth views from scrollView in cell and run the app, the scroll is not working because the height of the container in scrollView is less than the height of scrollView, so to solve this bug we will do two things.
1- we must set the height of the container in scrollView is more than the height of scrollView
2- set a bottom constraint for the last view in the container is less than or equal -50 (for example).
if you see the figure (A) we set the bottom Anchor is less than or equal -50, so it’s work fine,
but if you see figure (B) and when we add more views into the container, the bottom anchor become -50 and height of the container is increasing
Note:
if you design coding you use positive value when you set [leading, top] and
a negative value when you set[trailing, bottom], and if you design using storyboard, you use a positive value only
Let’s do it in our project.
First remove second, third, fourth views from the stack in cell and
In cell “CellScrollView”, inside scrollView Block we will add this line:
containerView.heightAnchor.constraint(greaterThanOrEqualTo: s.heightAnchor , multiplier: 1.01).isActive = true
this makes the height of the container in scrollView is greater than the scrollView by multiplier 1.01.
and replace this constraint for stackView :
stackViews.bottomAnchor.constraint(equalTo: containerView.bottomAnchor , constant: -8 ).isActive = true
to this line:
stackViews.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor , constant: -8).isActive = true
this makes the bottom constraint is less than or equal -8
When you run the app you can see the scrollView become scrollable.
And that is it. 🤩🥳💪
Case 3:
When the height of cells in tableView is less than the hight of tableView and trying to scroll to collapse header, you can see tableView scroll is unsmooth scrollable.
to try to see this bug you just set the number of cells equal 5 for tableView.
To fix this bug we need to create custom TableView and use it in the cell instead of UITableView.
import UIKit
class CustomTableView : UITableView {
override var adjustedContentInset: UIEdgeInsets {
if self.frame.height > contentSize.height {
let heightBottom =
( self.frame.height - contentSize.height ) + 0.5
return UIEdgeInsets(
top: self.contentInset.top + 0.5 ,
left: self.contentInset.left ,
bottom: heightBottom ,
right: self.contentInset.right ) }
return UIEdgeInsets(
top: self.contentInset.top + 0.5 ,
left: self.contentInset.left ,
bottom: self.contentInset.right ,
right: self.contentInset.right )
}
}
the solution is similar to Bug2, we check if the height of tableView is greater than the height of the contentSize then set bottom padding to make it scrollable and if you run the app you can see.
Case 4:
You can collapse header by scrolling scrollView or tableView but you can’t by gesture on viewHeader, so we will add panGesture on view to allow scrolling.
first thing we need to take object from viewHeader
@IBOutlet weak var viewHeader: UIView!
in viewDidLoad function add panGesture on viewheader
viewHeader.isUserInteractionEnabled = true
viewHeader.addGestureRecognizer(UIPanGestureRecognizer(target: self , action: #selector(handlePanGesture(_:))))
we need to implement the function handlePanGesture(_:)
@objc private func handlePanGesture (_ gesture : UIPanGestureRecognizer ) {
let translation = gesture.translation(in: viewHeader)
gesture.setTranslation(CGPoint(x: translation.x , y: 0.0), in:
viewHeader ) if translation.y > 0 &&
heightView.constant == headerViewMaxHeight {
return
}
if translation.y < 0 &&
heightView.constant == headerViewMinHeight {
return
} if let cell = collectionView.visibleCells.first as?
CellScrollView {
cell.scrollView.contentOffset.y =
cell.scrollView.contentOffset.y - translation.y }else if let cell = collectionView.visibleCells.first as?
CellTableView {
cell.tableView.contentOffset.y =
cell.tableView.contentOffset.y - translation.y }
}
Case 5 :
this bug is for RTL direction and we fixed it by add function
flipsHorizontallyInOppositeLayoutDirection in our custom flowLayout
Thanks for Abdoelrhman Mohamed for article
Thanks for Reading, Tap the 👏 button if you found this article useful!