UITableViewCell


#1

I have a very simple UIViewController with an enclosed UITableView. The tableviewcell for the table view is defined by 2 files;

  1. A class definition for the tableviewcell
  2. Storyboard XIB that has several of its graphical elements linked to the class definition (1)

In all non iPad views of the storyboard, there are no layout warnings. When I switch to an iPad Pro 10.5" portrait, still no errors BUT when I switch to landscape, I get a layout error that claims that the "expected width is 514 but actual width is 834”. This applies for all iPad views in landscape. The actual row outline does appear in dotted yellow, offset a bit to the top/left. If I tap the “Update Frames” button, then the error is gone but as soon as I select portrait and then switch back to landscape, the layout error re appears

Do you have any advice on how to rid me of this damn spot ?


#2

Do you have any screenshots you can share?

Supporting rotation is tricky. You have to make sure none of your constraints assume a “fixed” width or height.

It sounds like one of your constraints is set to a fixed distance, or you don’t have a view defined so that it can stretch properly.

I talk about this in my upcoming Auto Layout book.

  1. One and only one view in the horizontal (or vertical) direction can be stretchable.
  2. If you have more than one view that you want to stretch, you need to establish a relationship between how those two views will fill the space (i.e. a 50% equal width relationship)
  3. You may need to adjust a view so that it’s content hugging property is lower than one of the other views.
  4. Make sure you remove the constraint forcing a specific dimension (i.e. your 514 width constraint), instead use leading and trailing constraints to make it so that the edges are defined by the device bounds.
  5. You can skip rotation support and only support a portrait layout or a landscape layout, and you’ll save half the work. (Apple recommends all on iPad, but you only need to support one of these two groups (landscape left + landscape right) and/or (portrait + upside down)

#3

I’m thinking of doing a hands-on workshop with TableViewCell, .xib, and Auto Layout.

Would that be interesting to you? Let me know.


#4

Yes on the course

the first image displays the view controller

this screen displays the layout warning and the offset row outline in yellow

this screen displays the XIB file for the row design

I have tried all sorts of constraints, changes, etc and still can’t figure out what is going wrong


#5

Is there a reason you’re giving constraints to a prototype cell?

You should be able to just register the XIB with the Table View.

    let cell = UINib.init(nibName: "Cell", bundle: nil)
    tableView.register(cell, forCellReuseIdentifier: "Cell")

Assuming you had “Cell.xib” and then the .xib has all the constraints required to define it to stretch to fit.


#6

I hadn’t realized that I could just register the XIB with the table view WITHOUT constraints but that didn’t fix the problem either ( I had already been registering the XIB and the layout warning it still there when viewing iPad’s in landscape, WORSE, the warning now also appears when viewing on 8 Plus which didn’t happen with the constraints that I had applied ). Admittedly, I can resolve the warning on a temporary basis by tapping the “Update Frames” button in Xcode but as soon as I switch to a different view and then back to iPad landscape, the warning returns. See below screen capture


#7

While removing the constraints from the embedded UITableView I noticed that when the layout warning was visible, the visible representation of the UITableView was a blank area and then when I tapped there “OutLine Frames” button, the visible representation would appear with the text - Table View.

blank representation


#8

here is the same following tapping the “Update Frames”


#9

Resolved issue through brute force. I noticed that another similar window did NOT display the layout caution and started me wondering why. Here is the window hierarchy that works across all devices and orientations;


#10

What I have found in my testing is that there is a bug in the layout logic for these Storyboard files.

When you have Auto Layout in the Table View Cell (Prototype) it doesn’t re-layout the UI when you switch size classes. So it appears broken, and you have to force a layout update to update the positions, and clear the warnings.

Workaround #1:

  1. Select one view in the Table View Cell
  2. Size to Fit Content (Command + =)
  3. Update Frames (Command + Shift + =)

You’ll need to do this workaround any time you rotate or switch between Size Classes.

This is a bug with Storyboard + Size Classes + Prototype Cells, please report it to Apple Bug Report, and comment below. I will be filling a bug shortly (I have 20+ to send to Apple)

Workaround #2

  1. Don’t create Prototype cells in Storyboard files

  2. Make all your own UITableViewCell subclasses and Xib files that you register with the Table View in code

     let cell = UINib.init(nibName: "Cell", bundle: nil)
     tableView.register(cell, forCellReuseIdentifier: "Cell")
    
  3. Make sure you have a file named “Cell.swift” and “Cell.xib” with the TableViewCell class set to your class “Cell”