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
Related
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)
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)
}
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.
I have rotated my table view by 90°. Now I want to get indexpath of middle cell. When table view is not scrolling, it is showing 3 cells. What I want is, when table view stops scrolling, it should middle cell of green color. Sometimes I get wrong indexpath when more then 3 cells are visible while fast scrolling.
I have attached image for reference
try this
NSIndexPath *middleIndexPath = [tableView indexPathForRowAtPoint:CGPointMake(tableView.center.y, tableView.center.x)];
UITableViewCell *middleCell = [tableView cellForRowAtIndexPath:middleIndexPath];
You can get contentOffset of table view. With contentOffset, you can calculate current row (contentOffset.y / row height)
I'm looking to expand the height of the top cell in my collectionview with animation. The problem is when I detect a tap on the cell, I try animating the height and set the new height in the delegate: - collectionView:layout:sizeForItemAtIndexPath:indexPath. The issue I see an instant refresh after invalidating my collection flow layout and the animation happens afterwords. The effect I want is for the top cell to animate the expansion to the new height and push the rows beneath it along with the animation.
I'm only using one section with multiple rows. Should I try to use two sections and put the top cell in the first section and the remaining in the second section? Could I then animate the second section along with the height of the first section?
You need to do this three steps:
1.Invalidate your collectionViewLayout
self.collectionView.collectionViewLayout.invalidateLayout()
2.Reload desired indexPath or all the data inside a performBatchUpdates block
collectionView.performBatchUpdates({
self.collectionView.reload(at: DESIRED_INDEXPATH)
}, completion: nil)
3.Return the new height calculated in sizeForItemAtIndexpath delegate method