Prevent Uitableview Scrolling Below a Certain Point

Prevent UITableView scrolling below a certain point

You can use the property contentInset of UITableView just for that. Just remember to set them with minus values, cause we are shrinking the content size:

CGFloat insetTop = topAllowedRow * c_CELL_HEIGHT * -1;
CGFloat insetBottom = bottomAllowedRow * c_CELL_HEIGHT * -1;
[self.tableView setContentInset:UIEdgeInsetsMake(insetTop, 0, insetBottom, 0)];

The other solution is to implement UIScrollViewDelegate method scrollViewDidScroll: and when scrollView.contentOffset is too huge, set it back to the max value that user can scroll to:

- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
CGPoint scrollViewOffset = scrollView.contentOffset;
if (scrollViewOffset.x > MAX_VALUE) {
scrollViewOffset.x = MAX_VALUE;
}
[scrollView setContentOffset:scrollViewOffset];
}

First solution has both the advantage and disadvantage since then UIScrollView will manage the bouncing (just like in pull to refresh). It's more natural and HIG-compatible, but if you really need user not to see below the certain row, use delegate method.

How do I stop UITableview from scrolling more than one cell at a time

Thanks for your response. Here is how I solved it. I set:

  tableView.isScrollEnabled = false // Set the tableview scroll enabled to false

Then in the "cellForRowAt indexPath: IndexPath" function I saved the indexPath of the first row to the currentIndexPath property :

  currentIndexPath = indexPath

Then I added a gesture recognizer to the tableview for swiping up:

   let swipeToNextVideoGesture = UISwipeGestureRecognizer(target: self, action: 
#selector(swipeToNext(_:)))
swipeToNextVideoGesture.direction = .up
tableView.addGestureRecognizer(swipeToNextVideoGesture)

Then in the function I first checked if the next Row is in the tableview datasource array bounds, then I scrolled to that row:

    @objc private func swipeToNext(_ gesture: UISwipeGestureRecognizer) {
let nextVideoIndexPath = currentIndexPath.row+1
if !(nextVideoIndexPath >= viewModel.postInformations.count) {
currentIndexPath = IndexPath(row: nextVideoIndexPath, section: indexPathSection)
tableView.scrollToRow(at: currentIndexPath, at: .none, animated: true)
}
}

How to prevent a UITableView from being pulled down past a certain point?

Try this

extension ViewController: UIScrollViewDelegate
{
func scrollViewDidScroll(_ scrollView: UIScrollView)
{

print("ddffddfd \(scrollView.contentOffset.y)")

if scrollView.contentOffset.y > 0 && imageContainerViewHeightConstraint.constant == 223
{
return
}

if scrollView.contentOffset.y > 0
{

var sd = imageContainerViewHeightConstraint.constant + abs(scrollView.contentOffset.y)

if(sd < 233 )
{

print("path111 1")

self.dataTableView.contentOffset = CGPoint.init(x: 0, y: 0 )

return

}
else
{
print("path111 2")
imageContainerViewHeightConstraint.constant -= abs(scrollView.contentOffset.y)
}

print("path11111 3")
view.layoutIfNeeded()

self.dataTableView.contentOffset = CGPoint.init(x: 0, y: 0 )
return
}

print("path11111 4")

if scrollView.contentOffset.y < 0 && imageContainerViewHeightConstraint.constant >= initialContainerImageViewHeight * 2
{
self.dataTableView.contentOffset = CGPoint.init(x: 0, y: 0 )

//self.dataTableView.bounces = false

return
}
else
{
imageContainerViewHeightConstraint.constant += abs(scrollView.contentOffset.y)

view.layoutIfNeeded()

}

}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
resetContainerViewSize()
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
{
resetContainerViewSize()
}
}

///////

func resetContainerViewSize()
{
imageContainerViewHeightConstraint.constant = 223

UIView.animate(withDuration: 0.7,
delay: 0.0,
usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.5,
options: .curveEaseInOut,
animations: {
self.view.layoutIfNeeded()
self.dataTableView.bounces = true
}, completion: nil)
}

In Action

Sample Image

Find a demo here testScrollAboveTable

Prevent UITableView from scrolling when new cells are inserted

func add(_ item: Item) {
// Calculate your `contentOffset` before adding new row
let additionalHeight = tableView.contentSize.height - tableView.frame.size.height
let yOffset = tableView.contentOffset.y

// Update your contentInset to start tableView from bottom of page
updateTableContentInset()

items.append(item)

// Create indexPath and add new row at the end
let indexPath = IndexPath(row: objects.count - 1, section: 0)
tableView.insertRows(at: [indexPath], with: .top)

// Scroll to new added row if you are viewing latest messages otherwise stay at where you are
if yOffset >= additionalHeight {
tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
}

Here is the method to update contentInset. It will give you the same effect which you were achieving by this CGAffineTransform(scaleX: 1, y: -1)

func updateTableContentInset() {
var contentInsetTop = tableView.frame.size.height - tableView.contentSize.height
if contentInsetTop <= 0 {
contentInsetTop = 0
}
tableView.contentInset = UIEdgeInsets(top: contentInsetTop, left: 0, bottom: 0, right: 0)
}


Related Topics



Leave a reply



Submit