For reading ease and visual accessibility you should be using dynamic fonts whenever possible. Let’s look at an example you can get from the download files. I’ve run the Split View Controller from a previous tip in landscape on an iPad Pro 9.7 inch. Take a look at the labels on the table.

They are hard to read because they are so small. iOS has a system to make fonts bigger using dynamic type. Let’s look at a few issues with dynamic type programmatically.
For the user, they need to change one setting to make this bigger. ON the iPad simulator, click the Home button, and Settings. Select General>Accessibility,

Then Larger Text

On the bottom is a slider which you can notch up for larger text. For even larger text you can click on the switch on top. Make this pretty big.

That scales up the text in settings too. Go back to the app. You see bigger sizes but with white backgrounds,

The simulator has problems with this adjustment, which is why the white backgrounds. . Stop the app and re-run it.

By default, cells are dynamic text, the type called Body. Now rotate the simulator with a Command Left-Arrow, and drag out the master. Depending on the device, you may see the text wrap or get cut off.

To make sure it wraps, Head to the HueColorTableViewController
and the cellForRowAtIndexpath
method. Add the following line:
cell?.textLabel?.numberOfLines = 0
Setting the label property numberOfLines
to 0
does two things: it allows for a variable number of lines and activates a word wrap mode. Run again, and if you didn’t before, you’ll see our text wrap in the cells.

I still have a static font for my detail label. Head over there and You’ll see I have a UIFont
of 30-point American Typewriter. For dynamic type, You have two choices here. One is to use one of the system dynamic fonts. Add this to your code:
let dynamicFont = UIFont.preferredFont(forTextStyle: .title1)
The preferred Font method sets the font to the dynamic font title1
. I’ll change the font to the dynamic font:
colorLabel.font = dynamicFont
Run this

. This time, The font is a lot more visible, but on the system font. If I wanted a custom font, I’d have to do a few more steps. I’ll assign the colorLabel's
font to a class UIFontMetrics
and its default,
colorLabel.font = UIFontMetrics.default.scaledFont(for: font)
Finally, I need to tell the label to scale the font.
colorLabel.adjustsFontForContentSizeCategory = true
To be sure we get word wrapping, I’ll do this again
colorLabel.numberOfLines = 0
Run this. Change the font size to the smallest.

You’ll see the label remains at 30 point, as the Master dynamic type in the cells shrink.

Now make the font as large as it can get and run again. The font scales.

There is a complete course in the course library on accessibility which deep dives this topic and shows you the storyboard version of all this. It is something you should check out for better accessibility and adaptability of your user interface.
The Whole Code
Here’s the code for this week’s project. You can download the full project at Github.
HueColorTableViewController.swift
// // HueColorTableViewController.swift // ColorPicker // // // An exercise file for iOS Development Tips Weekly // by Steven Lipton (C)2018, All rights reserved // For videos go to http://bit.ly/TipsLinkedInLearning // For code go to http://bit.ly/AppPieGithub // import UIKit protocol HueColorTableViewControllerDelegate{ func didSelectColor(color:ColorEntry) } class HueColorTableViewController:UITableViewController{ var delegate:HueColorTableViewControllerDelegate! = nil var colors:[ColorEntry] = ColorModel().hues(count: 12) override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return colors.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCell(withIdentifier: "cell") if cell == nil { cell = UITableViewCell(style: .default, reuseIdentifier: "cell") } let row = indexPath.row cell?.contentView.backgroundColor = colors[row].color cell?.textLabel?.text = colors[row].name cell?.textLabel?.numberOfLines = 0 return cell! } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let row = indexPath.row title = colors[row].name delegate.didSelectColor(color: colors[row]) } override func loadView() { super.loadView() } }
ColorDetailViewController.swift
// // ColorDetailViewController.swift // ColorPicker // // An exercise file for iOS Development Tips Weekly // by Steven Lipton (C)2018, All rights reserved // For videos go to http://bit.ly/TipsLinkedInLearning // For code go to http://bit.ly/AppPieGithub // import UIKit class ColorDetailViewController: UIViewController, HueColorTableViewControllerDelegate { let colorLabel = UILabel() override func viewDidLoad() { super.viewDidLoad() addLayout() // Do any additional setup after loading the view. } //MARK:- Delegates func didSelectColor(color: ColorEntry) { view.backgroundColor = color.color colorLabel.text = color.name } //MARK:- Layout // All layout methods go here. func addLayout(){ colorLabel.text = "Color Detail" let font = UIFont(name: "AmericanTypewriter", size: 30)! //let dynamicFont = UIFont.preferredFont(forTextStyle: .title1) colorLabel.font = UIFontMetrics.default.scaledFont(for: font) colorLabel.adjustsFontForContentSizeCategory = true colorLabel.numberOfLines = 0 colorLabel.backgroundColor = .lightGray colorLabel.textAlignment = .center colorLabel.numberOfLines = 0 view.addSubview(colorLabel) colorLabel.translatesAutoresizingMaskIntoConstraints = false var constraints = [NSLayoutConstraint]() constraints += [NSLayoutConstraint(item: colorLabel, attribute: .leading, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .leading, multiplier: 1.0, constant: 0)] constraints += [NSLayoutConstraint(item: colorLabel, attribute: .trailing, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .trailing, multiplier: 1.0, constant: 0)] constraints += [NSLayoutConstraint(item: colorLabel, attribute: .top, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .top, multiplier: 1.0, constant: 0)] constraints += [NSLayoutConstraint(item: colorLabel, attribute: .height, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .height, multiplier: 1 / 9, constant: 0)] view.addConstraints(constraints) } }
ColorModel.swift
// // ColorModel.swift // ColorPicker // // // An exercise file for iOS Development Tips Weekly // by Steven Lipton (C)2018, All rights reserved // For videos go to http://bit.ly/TipsLinkedInLearning // For code go to http://bit.ly/AppPieGithub // import UIKit class ColorEntry{ var name:String = "" var color:UIColor var hue:CGFloat = 0.0 var brightness:CGFloat = 0.5 var saturation:CGFloat = 1.0 init(name:String,color:UIColor){ self.color = color self.name = name } } class ColorModel{ var colors = [ColorEntry]() init(){ colors = [] } func hues(count:Int)->[ColorEntry]{ colors = [] if count <= 0 {return colors} for hue in 0...count{ let hueValue = CGFloat(hue)/CGFloat(count) let color = UIColor(hue: hueValue, saturation: 1.0, brightness: 1.0, alpha: 1.0) let name = String(format:"H:%04.3f S:1.0 B:1.0 ",hueValue) let colorEntry = ColorEntry(name: name, color: color) colors += [colorEntry] } return colors } func lightnessScale(hue:UIColor,count:Int){ } }
Leave a Reply