Reputation: 569
I'm building my first real-world app after going through some tutorials and I've come across a layout issue. It is quite simple to adjust UI layout to different screen size classes, but I haven't found any information on how to adjust layout within same size class.
For example, I have a label whose Top Space constraint is set to 40 pt form top of view. It looks neat on a large iPhone 8 Plus screen:
But on a smaller iPhone SE screen (which is confusingly of same size class) this constraint of 40 pt pushes the label halfway through to the center, leaving reasonably less useful space below it:
So I was wondering if there's a way to set different constraints for different iPhones: say, 40 pt for iPhone 8 Plus, 30 pt for iPhone 8 and 20 pt for iPhone SE. Same goes about positioning other views below the label: I want them more compact vertical-wise on a small iPhone screen, and having more space between them on large screen. I know this last part can be solved with a stack view, but it's not always convenient to use.
UPD. Here is a full layout of the view on 8 Plus screen:
It has 3 fixed constraints: 1. From 'Title' label to top of the view - 50 pt 2. From 'Percent' label to bottom of 'Title' label - 60 pt 3. From 'Details' label to bottom of the view - 80 pt.
I've used text autoshrink in all labels + height of each label is proportional to view's height. This made layout a bit more flexible, but still there's a noticible issue on small SE screen:
As you can see, 'Details' is squeezed to 'Percent' label. At this point it would be great to move 'Percent' label higher up and closer to 'Title', but unlike heights constraints cannot be set in proportion (not in IB at least) to Superview height.
One of the options I see is to put a blank view between top and mid labels, making its height proportional and setting 'Percent' label top constraint at 0 to this blank view. Not sure though using such a "crutch" is a good practice.
Upvotes: 2
Views: 129
Reputation: 77462
You may get your most satisfactory results by using a single UILabel
and setting the Attributed Text, instead of trying to get multiple labels and font sizes to cooperate.
Try this:
UILabel
IBOutlet
then:
class ScalingViewController: UIViewController {
@IBOutlet weak var theLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let titleFont = UIFont.systemFont(ofSize: 80.0, weight: UIFontWeightThin)
let pctFont = UIFont.systemFont(ofSize: 100.0, weight: UIFontWeightThin)
let paraFont = UIFont.systemFont(ofSize: 30.0, weight: UIFontWeightLight)
// for blank lines between Title and Percent and between Percent and Body
let blankLineFont = UIFont.systemFont(ofSize: 36.0, weight: UIFontWeightLight)
let sTitle = "Title"
let sPct = "78%"
let sBody = "A detailed text explaining the meaning of percentage above and what a person should do to make it lower or higher."
// create the Attributed String by combining Title, Percent and Body, plus blank lines
let attText = NSMutableAttributedString()
attText.append(NSMutableAttributedString(string: sTitle, attributes: [NSFontAttributeName: titleFont]))
attText.append(NSMutableAttributedString(string: "\n\n", attributes: [NSFontAttributeName: blankLineFont]))
attText.append(NSMutableAttributedString(string: sPct, attributes: [NSFontAttributeName: pctFont]))
attText.append(NSMutableAttributedString(string: "\n\n", attributes: [NSFontAttributeName: blankLineFont]))
attText.append(NSMutableAttributedString(string: sBody, attributes: [NSFontAttributeName: paraFont]))
// these properties can be set in Interface Builder... or set them here to make sure.
theLabel.textAlignment = .center
theLabel.numberOfLines = 0
theLabel.adjustsFontSizeToFitWidth = true
theLabel.minimumScaleFactor = 0.05
// set the label content
theLabel.attributedText = attText
}
}
This gives me these results for 7+, 6s and SE:
And, just for demonstration's sake, how it looks with additional text in the "body" paragraph:
Upvotes: 1