Alternatives to tableView.scrollToRow() - ios

Problem
I need to have a UITableView reload with a specific cell positioned at the top of the tableview. For instance, have the 3rd cell in the tableView appear at the top of the tableView, rather than the 1st.
The issue in doing this comes from not being able to use the
self.tableView.scrollToRow(at: indexPath, at: .top, animated: false)
function, because I have a custom header that expands and collapse when the user scrolls. That means when I call the scrollToRow() function, my header collapses, messing things up.
Question
Is there any way to have a tableView open/reload with the 3rd cell positioned at the top of the tableView without using a "scroll" function?
Thanks!

You can follow below steps to fulfill your requirement:
Identify NSIndexPath of one of the visible cells.
Get its rectForRowAtIndexPath.
Get the current contentOffset of the table, itself.
Or, you can use scrollRectToVisible
This is how we use contentOffset:
mainTableView.setContentOffset(rectForRowAtIndexPath.point, animated: true)
And scrollRectToVisible:
mainTableView.scrollRectToVisible(rectForRowAtIndexPath.point, animated: true)

Related

Add New data from Bottom in TableView

When i add some text in TableView, it will show from Top of the tableview but i want to show it from bottom of tableView.
1. My TableView Screen
When i add user entered text in array and refresh tableView it will load from Top of TableView like below image.
but i want to add it from bottom like below image.
Can you guys help me, how can i achieve this?
Thanks
I am able to bind Data from bottom of TableView. All credit goes to Rajeshkumar R for helping me.
Step 1, apply a transform to the table view rotating it 180deg
tableView.transform = CGAffineTransformMakeRotation(-M_PI);
Step 2, rotate your raw cell 180deg in tableView:cellForRowAtIndexPath:
cell.transform = CGAffineTransformMakeRotation(M_PI);
Step 3, reverse your datasource. If you're using an NSMutableArray insert new objects at location 0 instead of using AddObject...
Now, the hard part is remembering that left is right and right is left only at the table level, so if you use
[tableView insertRowsAtIndexPaths:targetPath withRowAnimation:UITableViewRowAnimationLeft]
you can use the function below. It worked for me.
func scrollToLastRow() {
let indexPath = NSIndexPath(row: messageHistoryArray.count-1, section: 0)
self.createChatTableView.scrollToRow(at: indexPath as IndexPath, at: .bottom, animated: true)
}

UICollectionView cell scrolling issue in ios

On reloading the UICollectionView some time CollectionView cell does not bounce back. see the image collectionCell with title "Bgrawal ji Sourabh" should not be at this much distance from right side.It should have bounce.
Try this:
[self.collectionView scrollToItemAtIndexPath:yourDesiredIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
Please add below code before when your reload your collectionView
let indexes = NSIndexPath(forItem: 0, inSection: 0)
self.collectionViewSecond.scrollToItemAtIndexPath(indexes, atScrollPosition: .None, animated: false)
It's work for me hope work for you also!
Make sure you have enabled these two option in the CollectionView attribute Inspector i.e. Bounce on Scroll and Bounce on zoom this will allow the collectionView to give a bounce feed back on the scroll.

What is the expected `contentOffset` of UITableView when calling reloadData()?

I have a UITableView that displays custom cells. By pressing a button, the user can change the content of my UITableView
Scenario:
Load an array with 1000 elements
Scroll table to bottom (gives me about 20,000 contentOffset.y after scrolling)
On button pressed, I replace my array with 300 elements
Call reloadData in main thread (gcd)
After the step 4, what should be the correct new immediate contentOffset.y of my UITableView? I expected it to be 0 and my table scroll to top but for some reason it's not and does not scroll back to top. Is this the normal behavior of UITableView?
From Apple's docs... https://developer.apple.com/reference/uikit/uitableview/1614862-reloaddata
For efficiency, the table view redisplays only those rows that are
visible. It adjusts offsets if the table shrinks as a result of the
reload.
So, yes, it's normal to not scroll all the way to the top on reloadData.
If you want it to scroll to the top, either use setContentOffset or:
.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.top, animated: false)
Yes, It is normal behavior of UITableView. If you an want that table view should scrolled to top after reloading, you have to do that using below code.
let newOffset = CGPoint(x: currentOffset.x, y: 0)
tableView.setContentOffset(newOffset, animated: false)
Automatically, UITableView retain it's scroll offset while reloadData function called.

Stop TableView / TableViewCell animation (probably on willdisplaycell)

I've noticed this with a couple of UITableView's that I have coded, and that is when there is a lengthy list, or if I animate the displaying of the table itself, the cells have an animation, like the table is constructing the cells as I'm scrolling down.
The animation looks like the accessory view sliding from the left to the right, and I have a top-right label that does the same.
On another table that I slide in from the bottom, it looks like the buttons and text from the table expand as the table does.
How do I stop this?
I am using Swift, but if you know the answer in OBJ-C that would be okay too.
Also, if you need a preview, check this:
I've tried searching for this and I only get posts about making an animation within the table cells not removing this one!
So I found out how to stop it! It was because of the accessory view and making sure the cells have performed the layoutIfNeeded.
First, I removed the accessoryview from StoryBoard and in willDisplayCell: I used this:
UIView.performWithoutAnimation { () -> Void in
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
cell.layoutIfNeeded()
}
As well as:
UIView.performWithoutAnimation { () -> Void in
cell.layoutIfNeeded()
}
in cellForRowAtIndexPath:

Align row middle with UITableView middle

I have a UITableView that should show a particular row in its middle when it is first displayed. In viewDidLoad, I use scrollToRowAtIndexPath to achieve this:
// Center vertically on current row
let scrollIndexPath = NSIndexPath(forRow: currentRow, inSection: 0)
tableView.scrollToRowAtIndexPath(scrollIndexPath, atScrollPosition: UITableViewScrollPosition.Middle, animated: false)
This makes the top of the current row aligned with the middle of the table view meaning that the content of the row looks lower than it should be. How can I make the middle of the row align with the middle of the table view?
UITableView is a subclass of UIScrollView so you can use:
scrollRectToVisible:<#(CGRect)#> animated:<#(BOOL)#>
and calculate CGRect yourself, this way you have way more control than with using:
scrollToRowAtIndexPath

Resources