Table View Cells jump when selected on iOS 8 - ios

I'm trying to update my apps for iOS 8 and one strange issue that I can't figure out is that whenever I press a table view cell (on a grouped table view) and push another view controller on to the navigation controller, all the cells of the table view jump. It's sort of like they all reduce their height a little bit.
Consequently, when popping the navigation stack and coming back to the original table view screen, the cells jump again, this time they increase their height and going to back to how they were originally.
I have tried using a UITableViewController, doing my own table view management, not using explicity section heights, removing all custom header views and frames, basically anything I could think of.
It's happening on all the iOS 8 emulators and on actual devices runnings iOS 8 both iPhones and iPads.
Any suggestions will really help.
Edit: removed video

Alright, so if you're using the default UITableViewCells and setting custom fonts for the textLabel and detailTextLabel, make sure you either set rowHeight for the table view or implement one of the UITableViewDelegate methods for e.g. tableView:estimatedHeightForRowAtIndexPath:
The same code has worked fine on earlier versions of iOS, but needs fixing on iOS 8 for some reason.

I had the exact same problem!
It seems like the iOS 8 SDK uses the estimatedRowHeight, after selecting a row, which then results in a wrong height for the whole tableview, which causes the jumping of the tableview itself.
Not setting the estimatedRowHeight property or implementing the delegate method will fix the jumping bug.
I have not found a clean solution to fix it yet.

I solved the jumping problem with the Storyboard alone:
TableView Row Height: automatic.
TableView Estimate: my_value (e.g. 75)
TableView Cell Row Height: my_value

self.tableView.estimatedRowHeight=0;
self.tableView.estimatedSectionHeaderHeight=0;
self.tableView.estimatedSectionFooterHeight=0;

You can achieve self-sizing with this code:
implement together:
tableView.rowHeight = UITableViewAutomaticDimension;
tableView.estimatedRowHeight = CGFloatValue (initial estimated height);
in your storyboard, add the correct constraint on you cells.
Note: the jump issue will still show sometimes.
the exact solution for this jump issue is implementing the delegate method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return CGFloat;
}

Related

UITableview with Autolayout and NSFetchedResults controller cell layout bug on insert

I seem to be having a very strange problem with my UITableview cells and autolayout. So my tableview is set up as follows:
I have a UITableView within a UIViewController that I created via Interface builder using Autolayout
My tableview is using UITableViewAutomaticDimension so that the cells can resize based on the text within them.
Each cell has 2 subviews within it. A front view and a back view. The back view contains the buttons for my slide-able cells
I am using NSFetchedResults controller to update the tableview
The problem occurs when I tap on a cell and am taken to the next view. Then I create a core data item within that view and save so that it is inserted into my tableview (now behind the current view controller).
What happens is that the newly inserted cell seems to lose all autolayout constraints and all view elements are on top of each other in the top left of the cell. It also looks like they are not even contained within the front view for the cell (or the front view has a width and height of 0).
Example:
It gets even stranger. If I refresh the tableview by pulling down and the cells are reloaded it corrects itself. However, if I refresh the tableview again then the problem appears again but on a different cell. This bug does not happen consistantly which is rather frustrating.
Any help would be appreciated as I only have a few remaining hairs on my head to pull out at this stage.
Thanks in advance!
So I found out what the issue was. The issue was that I was using size classes in Interface builder but I was only using the iPhone Portrait size class and did all my work in there instead of the "any" size class. Disabling size classes and setting the project to iPhone only fixed all these problems.
Weird I know

Tableview within a tableview or autolayout nightmare

Looking for advice from more seasoned IOS dev's. I'm building with swift and autolayout storyboards. I have a cell within a table view that displays a picture and comments.
My problem is that any picture can have zero to several comments. I would like to limit it to two but I am now looking at having a tableview within a tableview cell. My other approach was to just add two comments and set the height to zero if comments for that picture have not been made yet. I started down the tableview within tableview (tableview inception) approach but shifted thinking that Apples autolayout would just pull everything in tight. Sadly tableView.rowHeight = UITableViewAutomaticDimension Turned out to be a layout nightmare and never did work right inspite of my carefully placed constraints. Am I missing a third obvious option. What would be your approach?
You can use view based NSTableView with 2 NSTableCellView.
PhotoWithComments NSTableCellView
WithoutComment NSTableCellView
I think using view based NSTableView would be easy then cell based NSTableView for your problem.

iOS dynamic height cell in tableview- issue with row 0 and 7

I am having a tableview in which I am displaying my data. As you can assume from the title, these cells are dynamic in their content, and so should their height be. Actually I got it working, but I have a strange issue with the row 0 and 7. These 2 rows take my entire screen, but when I scroll past them and go back again everything is fine. I am not sure but the 7. cell must be among the first cells that are being "dequed" when I scroll down. But as I said, this is just the first time they are being displayed, when I scroll again to one of them, everything is looking good (when filling the tableview with new data it is also fine).
I tried to reload the tableview twice when it is being populated for the first time, but without success. The presentation of the first cell I have fixed calling : self.tableView reloadAtIndexPaths ... when the table is being populated for the first time,
and it worked, it has the height it should have regarding its size. But I still have the issue with cell number 7 (the above fix does not work for this cell, I assume because it is not being displayed at that moment)
I am not using any fancy height calulation, just the iOS 8 feature:
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 80
Is there a method, fix with which i can force the tableview to draw the cells again ?
Thanks
Cell size is calculated from constrains. So I assume there is something wrong with those or with data during computation.
try this:
in tableview cell subclass use -prepareForReuse method to clean cell data as before reuse.

Adjusting the UiTableview hight in IB so the the table its able to scroll all the rows

I have a UITableView that is cutting off the last row and a half. I assume this is due to the face that I am using a navigation controller. What I can't figure out is how to adjust the height of the TableView so that it works on both iPhone 4 and 5's. If I adjust the height in IB to fit the iPhone 4, I have a large gap on the bottom of the iPhone 5. I would think there is some automatic way of doing this, but nothing I am trying seems to be working.
Auto Layout - Official Guide...
Also, if you're using a UITableViewController on the storyboard, this will solve your problem (with or without navigation controller, which is unrelated). If you're using a UITableView on a regular UIViewController, however, the best answer is auto-layout.

UITableViewController weird behavior after popping a view controller

My UITableView has a bunch of reusable cells, and when I tap on one of them, it takes me to another view controller (via push segue) showing the details of that cell (let's say it's an item, so it would show details about an item - name, price, image, etc...). When I pop that view controller (by tapping on the back button), the UITableView has a strange behavior:
a) if it's scrolled all the way to the bottom, it will scroll automatically tad up (around 50 points), leaving the last cell barely visible, so I have to scroll back down again. My cell all have 60 points for height.
b) the scrollbar always shows and then disappears, indicating that something is moving that UITableView (although if not scrolled to the bottom, the content will not move automatically).
This happens in multiple UITableView's I have in my app. I am not forcing a reload of the table view in viewWillAppear, so I don't understand what is happening. My content is static after loading from the server (unless the user changes it, and then the reload is executed). But simply showing details of an item and popping that VC doesn't change anything in the table view.
Edit: Okay, I've figured what the problem is: I'm hiding a UIToolbar when pushing that segue. If I keep it always visible (which I don't want), it still shows the scrollbars animating when popping in my table view but doesn't scroll the table view if on the last few rows.
Add the following to viewDidLoad.
self.automaticallyAdjustsScrollViewInsets = NO;
This solved my problem of table view moving down after navigating back to view controller.
I managed to fix the first issue. It seems like the tableview is not taking into account the 44 points of the UIToolbar.
Save the tableview offset in prepareForSegue: (save it in a CGPoint property)
self.tableViewScrollOffset = self.tableView.contentOffset;
Then, in viewWillAppear:, check if it has been modified. If so, restore it.
if(self.tableView.contentOffset.y != self.tableViewScrollOffset.y) {
[self.tableView setContentOffset:self.tableViewScrollOffset];
self.tableViewScrollOffset = CGPointZero;
}
This behavior is indeed a bug in iOS 8.x.
All answers given so far can not really solve the issue. The issue is, that iOS forgets (or doesn't) consider the previously calculated cell sizes, when a table is being redrawn for instance when the view is being pushed.
One approach to solve this can be found here: UITableView layout messing up on push segue and return. (iOS 8, Xcode beta 5, Swift) (so this question is even a duplicate to this one).
However, the solution provided there is overkill and there are certain situations why this caching will fail (for instance a UIContentSizeCategoryDidChangeNotification is not regarded)
But there is a quite simpler solution even though it is odd:
If you are using a manual performSequeWithIdentifier in didSelectRowAtIndexPath, just add a [self.tableView reloadData] just before.
If you are using a IB seque from the cell, just add [self.tableView reloadData] in your prepareForSeque code.
The reason, why this solves the issue is, that this will force iOS to re-estimate the visible cells and so it no longer scrolls the content to another location. Fortunately, tableView reloadData doesn't cost too much overhead here as only the visible cells will be re-estimated.
Just a hunch, have you got a rogue scrollToRowAtIndexPath:atScrollPosition:animated hanging around?
I was also facing this issue. I managed to find it out. The reason in my case is tableview header height was calculating based text and text height was negative due to which tableview was shifting down even though the contentinset and scrollinset are zero.
This was only occurring for first time. Next time it is calculating correct. One weired thing i found is that when Class A (having tableview) have pushed another Class B from init. When keyboard from Class B is opened viewDidLoad of Class A is called. and before Class B is unloaded from navigation controller. Tableview is reloaded for Class A.
Setting the automaticallyAdjustsScrollViewInsets as suggested above did not work neither did caching and setting the tableViewScrollOffset work.
Hence came up with an workaround which worked like a charm for me.
The workaround was to add an Dummy UIView which has height of 1px and width of 320px and place it between the "Top Layout Guide" and the UITableView. This view's background could be set to clear so that it is invisible.
Now using Autolayouts, fix the Dummy View's top to the Top. Now set the tableview's top constraint with respect to Dummy View. Found that this resolved the issue of the tableview's misplacement.
Screenshot of the Dummy View along with the autolayout constraints have been provided for easy reference. The Dummy View has been set to a larger height and red background colour for illustration purpose only.

Resources