Поддержка условных безопасных областей для Xib
Нет, мультиплатформенности Xib не существует. Вы можете попытаться продублировать свои Xib, построить их как Nibs независимо и получить к ним условный доступ во время выполнения в зависимости от версии iOS, но это, безусловно, не рекомендуется делать! У вас будет в два раза больше Xib и сложности для обработки. Гораздо проще поставить ограничения на Superview и изменить их константы из кода в зависимости от safeAreaInsets.
Поддержка Actual Safe Areas для кода
Ситуация аналогична Добавить поддержку макета iPhone X в старый проект Xcode 7/Swift 2:
Единственный способ получить поддержку безопасных областей — это использовать Xcode 9. Поэтому вы должны отказаться от поддержки iOS 7 и Swift 2.
После того, как вы используете Xcode 9, у вас может быть условный код:
Быстрый
extension UIApplication {
class var safeAreaInsets: UIEdgeInsets {
if #available(iOS 11.0, tvOS 11.0, *) {
return UIApplication.shared.delegate?.window??.safeAreaInsets ?? UIEdgeInsets.zero
}
return UIEdgeInsets.zero
}
}
ObjC
@interface UIApplication (extension)
+ (UIEdgeInsets)safeAreaInsets;
@end
@implementation UIApplication (extension)
+ (UIEdgeInsets)safeAreaInsets {
if (@available(iOS 11.0, tvOS 11.0, *)) {
UIWindow *window = UIApplication.sharedApplication.delegate.window;
return window != nil ? window.safeAreaInsets : UIEdgeInsetsZero;
}
return UIEdgeInsetsZero;
}
@end
Поддержка смоделированных безопасных зон для кода
Посмотрим правде в глаза, существует не так уж много разных форм устройств для поддержки (всего три случая: портрет с верхним вырезом, альбомный с верхним вырезом, другие). Таким образом, вы можете создать свои собственные значения безопасных областей на основе модели машины, и это может помочь вам со старыми версиями Xcode:
extension UIApplication {
/// on iPhone X+ portrait: top : 44.0, left : 0.0, bottom : 34.0, right : 0.0
/// on iPhone X+ landscape: top : 0.0, left : 44.0, bottom : 21.0, right : 44.0
/// on olders: top : 20.0, left : 0.0, bottom : 0.0, right : 0.0
class var safeAreaInsetsSimulated: UIEdgeInsets {
let model: String
if TARGET_OS_SIMULATOR != 0 {
model = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] ?? ""
} else {
var size = 0
sysctlbyname("hw.machine", nil, &size, nil, 0)
var machine = [CChar](repeating: 0, count: size)
sysctlbyname("hw.machine", &machine, &size, nil, 0)
model = String(cString: machine)
}
// will need adjustment in 2019
if model == "iPhone10,3" || model == "iPhone10,6" || model.starts(with: "iPhone11,") {
switch UIApplication.shared.statusBarOrientation {
case .landscapeRight, .landscapeLeft:
return UIEdgeInsets(top: 0, left: 44, bottom: 21, right: 44)
default:
return UIEdgeInsets(top: 44, left: 0, bottom: 34, right: 0)
}
}
return UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
}
}
Обратите внимание, что в первом фрагменте кода я возвращаю UIEdgeInsets.zero
по умолчанию, а в последнем фрагменте кода я возвращаю UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
по умолчанию: это просто вопрос выбора в зависимости от того, как вы хотите его обрабатывать, потому что Apple сделала выбор переопределить его между iOS 11 и iOS 12, что вызывает много проблем с совместимостью.
person
Cœur
schedule
19.09.2018