Often the UI of iOS applications is only designed for screens of one size. For example, iPhone X (375x812) or iPhone 13 (390x844), and then iOS developers make designs for screens of other sizes. With large screens, everything is simple. But placing the design of the iPhone X on the screen of the iPhone SE 2016 (1st gen.) is more difficult, some elements and indents have to be reduced manually. Screen design example for iPhone 13: 🥲 How it looks on different screens: 🙂 Result with UI scale: How to scale - Simple implementation We go through the UIView hierarchy and scale (almost) all the constraints. extension UIView { func callRecursively(level: Int = 0, _ body: (_ subview: UIView, _ level: Int) -> Void) { body(self, level) subviews.forEach { $0.callRecursively(level: level + 1, body) } } func scale() { // 390 is an iPhone 13 screen width var scaleFactor = min(UIScreen.main.bounds.width / 390, 1) callRecursively { (subview, level) in // to avoid scalе of system constraints guard level != 0 else { return } for constraint in subview.constraints { if constraint.constant != 0 { constraint.constant = CGFloat(constraint.constant) * scaleFactor } } } } } class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // one line is enough view.scale() } } And now let's make it a little more difficult for non-stretched screens func scale(kFor5: CGFloat? = nil, kFor8: CGFloat? = nil) { // 390 is an iPhone 13 screen width // 375 is for iPhone Х // and 320 is for iPhone SE 2016 (1st gen.) var scaleFactor = min(UIScreen.main.bounds.width / 390, 1) if let kFor5 = kFor5, UIScreen.main.bounds.width <= 320 { scaleFactor = scaleFactor * kFor5 } else if let kFor8 = kFor8, UIScreen.main.bounds.width <= 375, UIScreen.main.bounds.height <= 667 { scaleFactor = scaleFactor * kFor8 } callRecursively { (subview, level) in // to avoid scalе of system constraints guard level != 0 else { return } if let label = subview as? UILabel { label.scaleFont(scaleFactor) } else if let button = subview as? UIButton { button.scaleFont(scaleFactor) } for constraint in subview.constraints { if constraint.constant != 0 { constraint.constant = CGFloat(constraint.constant) * scaleFactor } } } } extension UILabel { func scaleFont(_ k: CGFloat) { let fontSize = font.pointSize font = font.withSize(fontSize * k) } } extension UIButton { func scaleFont(_ k: CGFloat) { let fontSize: Double = Double(titleLabel?.font.pointSize ?? 0.0) titleLabel?.font = titleLabel?.font.withSize(fontSize * k) } } class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // you can play with those factors for best results view.scale(kFor5: 0.75, kFor8: 0.85) } } Thank you for reading! That's all. Please write if you have any comments, I'm almost sure it can be improved further. Also, please let me know if you have solved a similar problem.