Мои 3 способа для выравнивания UI на разных девайсах в Swift

от автора

Итак, первый классический — обычный NSLayoutConstraint. Удобный, нативный и нисколько не обременяющий в написании. Но что если ваше приложение должно работать на iPhone SE 1 поколения? Тогда с вероятностью в 100% где-то вёрстка поедет. Для этого случая вы можете использовать UIDevice.current.

Второй помощник — UIDevice.current. Эта переменная, которую вы можете сами прописать в extension UIDevice. Она позволяет вам высчитывать размеры текущего устройства и исходя из этого создавать другие переменные и делегировать устройства по группам: таким, как isSmallScreen/isXScreenDevice . Но даже этого не всегда бывает достаточно, и приходится отказываться от разного рода дизайнерских решений.

extension UIDevice {     var iPhone: Bool {         return UIDevice().userInterfaceIdiom == .phone     }      enum ScreenType: String {         case iPhone8         case iPhone8Plus         case iPhoneX         case iPhoneXSMax         case iPhone11         case iPhone11Pro         case iPhoneSE         case iPhone12         case iPhone12Pro         case iPhone12Mini         case Unknown     }      var current: ScreenType {         guard iPhone else { return .Unknown}                  switch UIScreen.main.nativeBounds.height {         case 1136:             return .iPhoneSE         case 1334:             return .iPhone8         case 2208:             return .iPhone8Plus         case 2436:             return .iPhoneX         case 2521:             return .iPhone12         case 2532:             return .iPhone11Pro         case 2688:             return .iPhoneXSMax         case 2778:             return .iPhone12Pro         case 1792:             return .iPhone11         default:             return .Unknown         }     } }

И третий, о котором я узнал лишь на первой работе и больше нигде его не применял. Для этого мы создаём константы screenHeight и screenWidth, которые равны UIScreen.main.bounds.height/width . При использовании в NSLayoutConstraint придерживаемся такой формулировки:

// Для вертикальных констрейнтов (например topAnchor, bottomAnchor) 20/812*screenHeight // Для горизонтальных констрейнтов (например leadingAnchor, trailingAnchor) 20/375*screenWidth

Этот вариант практически идеально позволяет распределить UI-объекты на разных устройствах, и элементы вашего приложения будут выглядеть всегда одинаково и на iPhone 14 Pro Max, и на iPhone SE.

При первом взгляде это самый подходящий вариант. Однако чем чаще его используешь, тем больше приходит понимание, что это не панацея, а скорее не нужный, объёмный «костыль», который заполоняет весь код магическими числами и непременно вызовет негодование у вашего тимлида. Поэтому я бы рекомендовал его использовать только в редких случаях.

NSLayoutConstraint.activate([             secondTitleLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -156/812*screenHeight),             secondTitleLabel.rightAnchor.constraint(equalTo: view.rightAnchor),             secondTitleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),             secondTitleLabel.leftAnchor.constraint(equalTo: view.leftAnchor)         ])                  NSLayoutConstraint.activate([             mainTitleLabel.bottomAnchor.constraint(equalTo: secondTitleLabel.topAnchor, constant: -32/375*screenWidth),             mainTitleLabel.rightAnchor.constraint(equalTo: view.rightAnchor),             mainTitleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),             mainTitleLabel.leftAnchor.constraint(equalTo: view.leftAnchor)         ])

В заключение скажу, что спустя время я чаще прибегаю к обычной работе констрейнтов, и их всегда хватает с головой. Иногда в редких случаях я использую UIDevice.current. И практически никогда третий вариант.

Экспериментируйте! Если найдёте для себя полезным тот или иной вариант, попробуйте его в своём проекте. Если я упустил что-то, не стесняйтесь поделиться этим в комментариях.

Надеюсь, эта статья была для вас полезна.


ссылка на оригинал статьи https://habr.com/ru/post/709088/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *