Swift UITableView scrollToRow not working - swift

I have a tableView with multiple lines and textFields. Some of the textFields won't be visible when the keyboard is visible. So I want the selected row to scroll to top to be visible.
I'm using
let indexPath = IndexPath(row: index, section: 0)
tableViewActivity.scrollToRow(at: indexPath, at: .top, animated: true)
for this to scroll the selected row to top. This code is inside textFieldDidBeginEditing and is called correctly, but the tableView does nothing, there is no scroll. I found a post with a workaround for some by using a delay or reload the Data before scrolling, but nothing changed for me with this. So can anybody help me please?

Related

how to show the middle cell of a collection view when my app starts

I have a collectionView embedded in a subview of the ViewController. The collectionView has 12 cells. Each cell takes up the whole width and height of the collection view, so that I can achieve the pagination affect. However, when the app starts, I want to show the middle cell like the 6th or 7th one of my collectionView.
P.S. I have the collectionView in a wrapper view, not in my viewController.
In my WrapperView, I added the following method but as this method is called after the collectionView is added, it shows a sudden jump.
override func didAddSubview(_ subview: UIView) {
super.didAddSubview(subview)
let indexPath = IndexPath(row: 6, section: 0)
DispatchQueue.main.async {
self.calendarCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: false)
}
}
If I could do it before the collection view appear on the screen, I may be able to fix that problem, but I can't find which method is called before the didAddSubview(_:) method in UIView Life Cycle.
Can anyone give me hint on how to solve this.
After your data source has loaded use:
func selectItem(at indexPath: IndexPath?,
animated: Bool,
scrollPosition: UICollectionView.ScrollPosition)
https://developer.apple.com/documentation/uikit/uicollectionview/1618057-selectitem
Probably best used before the view appears so trigger in viewWillAppear or viewDidLoad

Swift 3 - Scroll to top of Tableview on Tabbar Switch

I have a few UITableViewController's set up as child-views of UINavigationController's that are all part of a single UITabBarController. One of these UITableViewController's updates a tableViewController that is part of a different UITableViewController on a button press, which then switches the currently selected tab via:
self.tabBarController?.selectedIndex = 1
I would like the tableView in the newly selected index, in this case 1,to scroll back to the top automatically on changing between the tabViews. I have tries simply adding :
self.tableView.setContentOffset(CGPoint.zero, animated: true)
To viewWillAppear() but this doesn't seem to work. If you scroll to the bottom of the tableView on index 1, then tab over to the tabBarController that updates that index(say index 0), update the index and get switched back to index 1, the tableview for index 1 remains on the same row as when you originally were viewing it. The data is properly loaded, but the actual UI is still on the row you left at. I would like to implement it so that switching between tabs automatically scrolls to the top.
You can try using IndexPath and scroll to index 0 of section 0 :
let indexPath = IndexPath(row: 0, section: sectionIndex) // set row = 0 and section = 0
self.tableView.scrollToRow(at: indexPath, at: .top, animated: false)
You can use scrollToRow(at:at:animated:).
You can add this to the viewWillAppear(_ animated: Bool) function:
let indexPath = IndexPath(item: 0, section: 0)
tableView.scrollToRow(at: indexPath, at: .top, animated: false)

UICollectionView inside a tableviewcell: scrollToIndex not working

I have created a simple UICollectionView inside of a tableviews, UITableviewCell. The collection view is set to scroll horizontally. I am trying to scroll to a certain element within the collection view using scrollToIndex at:, I have placed the scroll request in the tableviewcell's layoutSubviews method. When the collection view is displayed, no scrolling takes place.
Here is the tableviewcell's layoutSubviews code:
override func layoutSubviews() {
super.layoutSubviews()
let indexPath = IndexPath(item: 1, section: 0)
self.collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.left , animated: false)
}
It's quite simple, so really not sure why this is not working?
Many thanks for any help!

Returning to the same scroll position of UICollectionView after tapping a cell

I have a UICollectionView that is populated with all photos from the devices photo library. After a cell (photo) is tapped, it segues to a view controller that allows for editing. On this view, there is an "Add Photo" button to return the user back to the UICollectionView (to select another photo). I need for the scroll position to "focus" the previous tapped cell in the center of the view without any animations or jumping.
I have tried saving the tapped indexPath as a variable, then on viewDidAppear, scroll to that indexPath with scrollToItemAtIndexPath. The problem is I can't figure out how to update a variable (to save indexPath) on cell tap. I tried this in didSelectItemAtIndexPath, but the value never actually saves.
var cellTappedIndexPath = Int()
Inside didSelectItemAtIndexPath:
cellTappedIndexPath = indexPath.row
The value for cellTappedIndexPath never saves.
Just for testing out scrollToItemAtIndexPath, I have added the following to viewDidAppear:
customViewCollectionView.scrollToItemAtIndexPath(NSIndexPath(forItem: 25, inSection: 0), atScrollPosition: UICollectionViewScrollPosition.CenteredVertically, animated: false)
// 25 is just a number I have set for testing. Ultimately, I would like this to be the saved indexPath of the last tapped cell.
This causes the collectionView to "jump" to cell 25 once it's fully loaded. If I set animated to true, it loads at the top, then scrolls down to cell 25. Not my desired result.
I just want to be able to do 2 things here.
1 - Save the cell tapped as a variable.
2 - use scrollToItemAtIndexPath (with the variable in #1) so the view just loads up instantly with the last cell tapped right into the middle, No animations or anything.
Let me know if further clarification is needed. THANKS!
You could save the selected indexPathreceived when the collectionview cell is tapped and use it when required.
var selectedIndexPath: NSIndexPath?
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedIndexPath = indexPath
}
func scrollToCell(){
if let index = selectedIndexPath{
customViewCollectionView.scrollToItemAtIndexPath(index, atScrollPosition: .CenteredVertically, animated: false)
}else{
print("A cell hasnt been selected yet")
}
}

Auto height cell after add text

I have tableView and when i type i want auto height cell. But i don't know how to fix it. My first idea was:
self.chatTableView.cellForRowAtIndexPath(indexPath)?.textLabel?.text = new_char
self.chatTableView.cellForRowAtIndexPath(indexPath)?.sizeToFit()
self.chatTableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
When i have this line with .sizeToFit() my result looks like this:
But when i comment this line:
self.chatTableView.cellForRowAtIndexPath(indexPath)?.textLabel?.text = new_char
self.chatTableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
My result looks this:
Is any way to fix it ?
You have changed the height of your UITableViewCell directly. But the height of the cell is handled in the UITableView. To make this work you have to do two things:
1. Use self sizing cells:
Just add this two lines of code to your viewDidLoadmethod:
override func viewDidLoad() {
super.viewDidLoad()
...
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 40
}
The estimatedRowHeight is only used to calculate the scroll bar size and position so you just put the normal expected height of your cells here.
2. Reload the cell after you changed the text
After you changed the text of your cell's label, you have to tell the UITableView to reload this cell so that its height gets adjusted. You do this by calling this method:
func addSomeText() {
// add the text to your data source
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
Obviously the indexPath is your cell's indexPath.
One important thing: You cannot add the new text directly to the cell. Instead you have to add it to your dataSource. Otherwise the text will be gone after the reload, because the cell gets its text from the dataSource when it is dequeued.