Last week, a refresh of the design of my client's app called for a layout that changed depending on the device orientation. We're using AutoLayout and didn't want to use any deprecated methods.
Problem was that it called for layout changes within a UITableViewCell. I thought of a way to do this with AutoLayout but the constraints would become quite complex. Instead, I took the following approach:
Thus the UITableViewCell subclass looks as follows:
class CustomTableCell : UITableViewCell {
@IBOutlet weak var dateLabel: UILabel!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var trailingConstraint: NSLayoutConstraint!
}Problem is: where can you set properties all the currently visible cells? The easiest way I could come up with, is in the cellForRowAtIndexPath() function. The view controller class has the following property:
var size: CGSize = CGSizeZero
The viewWillTransitionToSize() function stores the new screen size and asks the UITableView to reload:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
self.size = size
NSLog("viewWillTransitionToSize self.size = \(self.size)")
self.tableView!.reloadData()
}And when dequeueing new cells, we set the constraint its constant:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TestCell") as CustomTableCell!
NSLog("self.size=\(self.size)")
cell.nameLabel.text = self.items[indexPath.row]
if self.size.width > self.size.height { //Landscape
NSLog("Landscape")
cell.trailingConstraint.constant = 100
} else { //Portrait
NSLog("Portrait")
cell.trailingConstraint.constant = 0
}
return cell
}Because viewWillTransitionToSize() is not called when the View Controller is run for the first time, I also added the following code to viewWillLayoutSubviews():
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
// Only run once, upon first display
if self.size == CGSizeZero {
self.size = self.tableView!.frame.size
NSLog("viewWillLayoutSubviews self.size = \(self.size)")
}
}Download the example project: TestTableViewCellSizing.zip
Note: I created the above truly breathtaking animated gif by taking a screen recording with QuickTime Player, running the iOS Simulator, then converting the resulting .mov file with the following ffmpeg command:
ffmpeg -i example.mov -r 15 example.gif
ffpmeg was installed via Homebrew.