Получите одинаковый пользовательский интерфейс для всех экранов iPhone, используя масштабирование NSLayoutConstraint

Получите одинаковый пользовательский интерфейс для всех экранов iPhone, используя масштабирование NSLayoutConstraint

17 апреля 2022 г.

Часто пользовательский интерфейс iOS-приложений предназначен только для экранов одного размера. Например, iPhone X (375x812) или iPhone 13 (390x844), а затем разработчики iOS делают дизайны для экранов других размеров.


С большими экранами все просто. А вот разместить дизайн iPhone X на экране iPhone SE 2016 (1-го поколения) сложнее, некоторые элементы и отступы приходится уменьшать вручную.


Пример дизайна экрана для iPhone 13:



🥲 Как это выглядит на разных экранах:



🙂 Результат с масштабированием пользовательского интерфейса:



Как масштабировать — простая реализация


Мы проходим через иерархию UIView и масштабируем (почти) все ограничения.


```цельc


расширение UIView {


func callRecursively(level: Int = 0, _ body: (_ subview: UIView, _ level: Int) -> Void) {


тело (я, уровень)


subviews.forEach { $0.callRecursively(уровень: уровень + 1, тело)}


функция масштаба () {


// 390 — это ширина экрана iPhone 13


вар масштабный фактор = мин (UIScreen.main.bounds.width / 390, 1)


callRecursively { (подвид, уровень) в


// чтобы избежать масштабирования системных ограничений


уровень охраны != 0 иначе { возврат }


для ограничения в subview.constraints {


если ограничение.константа!= 0 {


ограничение.константа = CGFloat(ограничение.константа) * коэффициент масштабирования


```цельc


класс ViewController: UIViewController {


переопределить функцию viewDidLoad() {


super.viewDidLoad()


// достаточно одной строки


вид.масштаб()


А теперь давайте немного усложним задачу для нерастянутых экранов


```цельc


func scale(kFor5: CGFloat? = nil, kFor8: CGFloat? = nil) {


// 390 — это ширина экрана iPhone 13


// 375 для iPhone Х


// и 320 для iPhone SE 2016 (1-го поколения)


вар масштабный фактор = мин (UIScreen.main.bounds.width / 390, 1)


если пусть kFor5 = kFor5,


UIScreen.main.bounds.width <= 320 {


масштабный коэффициент = масштабный коэффициент * kFor5


} иначе, если пусть kFor8 = kFor8,


UIScreen.main.bounds.width <= 375,


UIScreen.main.bounds.height <= 667 {


масштабный коэффициент = масштабный коэффициент * kFor8


callRecursively { (подвид, уровень) в


// чтобы избежать масштабирования системных ограничений


уровень охраны != 0 иначе { возврат }


если пусть label = subview как? UILabel {


label.scaleFont(масштабныйКоэффициент)


} else if let button = subview as? UIButton {


button.scaleFont(масштабныйфактор)


для ограничения в subview.constraints {


если ограничение.константа!= 0 {


ограничение.константа = CGFloat(ограничение.константа) * коэффициент масштабирования


```цельc


расширение UILabel {


func scaleFont(_ k: CGFloat) {


пусть fontSize = font.pointSize


шрифт = font.withSize (размер шрифта * k)


```цельc


расширение UIButton {


func scaleFont(_ k: CGFloat) {


пусть fontSize: Double = Double (titleLabel?.font.pointSize ?? 0.0)


titleLabel?.font = titleLabel?.font.withSize(fontSize * k)


```цельc


класс ViewController: UIViewController {


переопределить функцию viewDidLoad() {


super.viewDidLoad()


// вы можете поиграть с этими факторами для достижения наилучших результатов


view.scale(kFor5: 0,75, kFor8: 0,85)


Спасибо за чтение!


Это все. Пожалуйста, напишите, если у вас есть какие-либо комментарии, я почти уверен, что это можно улучшить дальше. Также, пожалуйста, дайте мне знать, если вы решили подобную проблему.



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE