2015-02-01 Layout of a tableviewcell depending upon device orientation

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)")

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!
		cell.nameLabel.text = self.items[indexPath.row]
		if self.size.width > self.size.height { //Landscape
			cell.trailingConstraint.constant = 100
		} else { //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() {
		// Only run once, upon first display
		if self.size == CGSizeZero {
			self.size = self.tableView!.frame.size
			NSLog("viewWillLayoutSubviews self.size = \(self.size)")

layout uitableviewcell depending upon device orientation.gif

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.