I have a typical master-detail app that allows the user to browse a scrolling list of objects, and then drill to detail for any particular object with a push segue. The scrolling master list is a UITableView built with prototype cells, and the detail scene is a static UITableView with a fixed number of sections and cells.
I would like to implement Dynamic Type and Self-Sizing Cells in my app so that the user can change the base font size. So far, I have been successful making self-sizing cells with the scrolling list of prototype cells: by using Auto Layout, setting number of lines in each label to 0, and setting tableView.rowHeight = UITableViewAutomaticDimension
, the height of each prototype cell grows or shrinks to accommodate the size of the text within.
But I can't achieve the same effect in my static table view. Whether I use custom cells or built-in cell types, the font grows/shrinks but the cell height does not.
So my question is actually two questions: 1) is it possible to implement self-sizing cells in static table views, like I've done with my prototype table view? and 2) if the answer to the first question is no, how do I write code that will measure the height of a label in a static table view cell and adjust the cell height appropriately?
Thank you!
I'm grateful for the answers provided to the question I posted yesterday. Unfortunately (and likely because of my own inexperience as an iOS programmer) I was not able to make the systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) approach work. After some trial and error, however, I found a different method that seems to work:
import UIKit
class MasterTVC: UITableViewController {
@IBOutlet weak var staticCustomCellLabel: UILabel!
//viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.estimatedRowHeight = 44.0
staticCustomCellLabel.text = "This is the text for the static custom cell label; This is the text for the static custom cell label; This is the text for the static custom cell label"
//Register handleDynamicTypeChange in observer: self
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleDynamicTypeChange:", name: UIContentSizeCategoryDidChangeNotification, object: nil)
}
//deinit
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
//handleDynamicTypeChange
//called when user changes text size in Settings > General > Accessibility > Larger Text
//or Settings > Display & Brightness > Text Size
func handleDynamicTypeChange(notification: NSNotification) {
staticCustomCellLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
self.tableView.reloadData()
}
//tableView:heightForRowAtIndexPath
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
}
On the Storyboard side of this, the setup begins with a single Table View Controller with the following properties:
Section-1:
Table View Cell:
The UILabel is further configured as:
This worked for me designing for iOS 9 in Xcode 7 and Swift 2 with Auto Layout enabled. The interesting thing is that if you strip away the NSNotificationCenter code that is used to respond immediately to changes in text size, the self-sizing cells code is basically two lines: setting estimatedRowHeight in viewDidLoad, and returning UITableViewAutomaticDimension from tableView:heightForRowAtIndexPath.
Based on these results, I believe the answers to my original question are: 1) yes; and 2) see 1.