जवाबों:
इसे इस्तेमाल करे :
में उद्देश्य सी
if (@available(iOS 11.0, *)) {
UIWindow *window = UIApplication.sharedApplication.keyWindow;
CGFloat topPadding = window.safeAreaInsets.top;
CGFloat bottomPadding = window.safeAreaInsets.bottom;
}
में स्विफ्ट
if #available(iOS 11.0, *) {
let window = UIApplication.shared.keyWindow
let topPadding = window?.safeAreaInsets.top
let bottomPadding = window?.safeAreaInsets.bottom
}
keyWindow
हमेशा nil
ऐसा था कि मैंने इसे बदल windows[0]
दिया और ?
वैकल्पिक चैनिंग से हटा दिया , फिर इसने काम किया।
लेआउट गाइड के बीच की ऊँचाई प्राप्त करने के लिए आप बस करते हैं
let guide = view.safeAreaLayoutGuide
let height = guide.layoutFrame.size.height
तो full frame height = 812.0
,safe area height = 734.0
नीचे उदाहरण है जहां हरे रंग के दृश्य का फ्रेम है guide.layoutFrame
UIApplication.sharedApplication.keyWindow.safeAreaLayoutGuide.layoutFrame
, जिसमें सुरक्षित फ्रेम है।
स्विफ्ट 4, 5
किसी सुरक्षित क्षेत्र के एंकर को देखने के लिए बाधाओं का उपयोग करते हुए व्यू कंट्रोलर के जीवनचक्र में कहीं भी किया जा सकता है क्योंकि वे एपीआई द्वारा पंक्तिबद्ध होते हैं और दृश्य को मेमोरी में लोड होने के बाद हैंडल किया जाता है। हालाँकि, सुरक्षित-क्षेत्र मान प्राप्त करने के लिए व्यू कंट्रोलर के जीवनचक्र के अंत की प्रतीक्षा करने की आवश्यकता होती है, जैसे viewDidLayoutSubviews()
।
यह किसी भी दृश्य नियंत्रक में प्लग करता है:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let topSafeArea: CGFloat
let bottomSafeArea: CGFloat
if #available(iOS 11.0, *) {
topSafeArea = view.safeAreaInsets.top
bottomSafeArea = view.safeAreaInsets.bottom
} else {
topSafeArea = topLayoutGuide.length
bottomSafeArea = bottomLayoutGuide.length
}
// safe area values are now available to use
}
मैं इस पद्धति को विंडो से दूर होने के लिए पसंद करता हूं (जब संभव हो) क्योंकि यह है कि एपीआई कैसे डिज़ाइन किया गया था और इससे भी महत्वपूर्ण बात यह है कि मूल्यों को सभी दृश्य परिवर्तनों के दौरान अपडेट किया जाता है, जैसे डिवाइस ओरिएंटेशन परिवर्तन।
हालाँकि, कुछ कस्टम प्रस्तुत दृश्य नियंत्रक उपरोक्त विधि का उपयोग नहीं कर सकते हैं (मुझे संदेह है क्योंकि वे क्षणिक कंटेनर विचारों में हैं)। ऐसे मामलों में, आप रूट व्यू कंट्रोलर से मान प्राप्त कर सकते हैं, जो हमेशा वर्तमान व्यू कंट्रोलर के जीवनचक्र में कहीं भी उपलब्ध होगा।
anyLifecycleMethod()
guard let root = UIApplication.shared.keyWindow?.rootViewController else {
return
}
let topSafeArea: CGFloat
let bottomSafeArea: CGFloat
if #available(iOS 11.0, *) {
topSafeArea = root.view.safeAreaInsets.top
bottomSafeArea = root.view.safeAreaInsets.bottom
} else {
topSafeArea = root.topLayoutGuide.length
bottomSafeArea = root.bottomLayoutGuide.length
}
// safe area values are now available to use
}
viewDidLayoutSubviews
(जिसे कई बार कहा जा सकता है), यहाँ एक समाधान है जो इसमें भी काम करेगा viewDidLoad
: stackoverflow.com/a/53864017/7767664
यहां किसी भी अन्य उत्तर ने मेरे लिए काम नहीं किया, लेकिन यह किया।
var topSafeAreaHeight: CGFloat = 0
var bottomSafeAreaHeight: CGFloat = 0
if #available(iOS 11.0, *) {
let window = UIApplication.shared.windows[0]
let safeFrame = window.safeAreaLayoutGuide.layoutFrame
topSafeAreaHeight = safeFrame.minY
bottomSafeAreaHeight = window.frame.maxY - safeFrame.maxY
}
यहाँ सभी उत्तर उपयोगी हैं, उन सभी को धन्यवाद जिन्होंने मदद की पेशकश की।
हालाँकि जैसा कि मैं देख रहा हूँ कि सुरक्षित क्षेत्र विषय थोड़ा भ्रमित है जो अच्छी तरह से प्रलेखित नहीं होगा।
इसलिए मैं इसे यहीं पर संक्षेप में प्रस्तुत करूंगा ताकि इसे समझना आसान हो सके safeAreaInsets
, safeAreaLayoutGuide
और LayoutGuide
।
IOS 7 में, Apple ने प्रॉपर्टीज topLayoutGuide
और bottomLayoutGuide
प्रॉपर्टीज पेश कीं UIViewController
, उन्होंने आपको अपनी कंटेंट को UIKit बार जैसे कि स्टेटस, नेविगेशन या टैब बार से छुपाकर रखने के लिए अड़चनें पैदा करने की अनुमति दी। कंटेंट पर कॉन्ट्रैक्ट्स को निर्दिष्ट करने के लिए इन लेआउट गाइड्स से संभव था, इसे टालें। ऊपर या नीचे नेविगेशन तत्वों (UIKit बार, स्टेटस बार, नेवी या टैब बार ...) द्वारा छिपा होना।
उदाहरण के लिए यदि आप एक तालिका बनाना चाहते हैं तो शीर्ष स्क्रीन से शुरू होता है, जो आपने कुछ इस तरह किया है:
self.tableView.contentInset = UIEdgeInsets(top: -self.topLayoutGuide.length, left: 0, bottom: 0, right: 0)
IOS 11 में Apple ने इन संपत्तियों को एक सुरक्षित क्षेत्र लेआउट गाइड के साथ बदल दिया है
Apple के अनुसार सुरक्षित क्षेत्र
सुरक्षित क्षेत्र आपके विचारों को समग्र इंटरफ़ेस के दृश्य भाग के भीतर रखने में मदद करते हैं। यूआईआईआईटी-परिभाषित दृश्य नियंत्रक आपकी सामग्री के शीर्ष पर विशेष विचार रख सकते हैं। उदाहरण के लिए, एक नेविगेशन नियंत्रक अंतर्निहित दृश्य नियंत्रक की सामग्री के शीर्ष पर एक नेविगेशन बार प्रदर्शित करता है। यहां तक कि जब इस तरह के विचार आंशिक रूप से पारदर्शी होते हैं, तब भी वे उस सामग्री को रोक देते हैं जो उनके नीचे है। टीवीओएस में, सुरक्षित क्षेत्र में स्क्रीन के ओवरस्कैन इनसेट भी शामिल होते हैं, जो स्क्रीन के बेज़ेल द्वारा कवर किए गए क्षेत्र का प्रतिनिधित्व करते हैं।
नीचे, एक सुरक्षित क्षेत्र iPhone 8 और iPhone X-Series में हाइलाइट किया गया है:
की safeAreaLayoutGuide
संपत्ति हैUIView
की ऊंचाई पाने के लिए safeAreaLayoutGuide
:
extension UIView {
var safeAreaHeight: CGFloat {
if #available(iOS 11, *) {
return safeAreaLayoutGuide.layoutFrame.size.height
}
return bounds.height
}
}
जो आपके चित्र में एरो की ऊँचाई को लौटा देगा।
अब, शीर्ष "पायदान" और नीचे होम स्क्रीन सूचक ऊंचाइयों को प्राप्त करने के बारे में क्या?
यहां हम इसका उपयोग करेंगे safeAreaInsets
एक दृश्य का सुरक्षित क्षेत्र नेविगेशन बार, टैब बार, टूलबार और अन्य पूर्वजों द्वारा कवर किए गए क्षेत्र को दर्शाता है जो एक दृश्य नियंत्रक के दृश्य को अस्पष्ट करते हैं। (टीवीओएस में, सुरक्षित क्षेत्र स्क्रीन के बेज़ेल द्वारा कवर नहीं किए गए क्षेत्र को दर्शाता है।) आप इस संपत्ति में इनसेट को दृश्य की सीमा आयत पर लगाकर दृश्य के लिए सुरक्षित क्षेत्र प्राप्त करते हैं। यदि दृश्य वर्तमान में दृश्य पदानुक्रम में स्थापित नहीं किया गया है, या अभी तक ऑनस्क्रीन दिखाई नहीं दे रहा है, तो इस गुण में किनारे वाले इनसेट 0 हैं।
निम्नलिखित असुरक्षित क्षेत्र दिखाएगा और iPhone 8 और iPhone X-Series में से एक पर किनारों से दूरी होगी।
अब, यदि नेविगेशन बार जोड़ा गया है
तो, अब असुरक्षित क्षेत्र ऊंचाई कैसे प्राप्त करें? हम उपयोग करेंगेsafeAreaInset
हालांकि वे समाधान के लिए एक महत्वपूर्ण बात में भिन्न हैं,
पेहला:
self.view.safeAreaInsets
EdgeInsets को लौटाएगा, अब आप इनसेट्स को जानने के लिए ऊपर और नीचे तक पहुंच सकते हैं,
दूसरा:
UIApplication.shared.windows.first{$0.isKeyWindow }?.safeAreaInsets
पहला वह जिसे आप इनसेट देख रहे हैं, इसलिए यदि कोई नेविगेशन बार है तो उस पर विचार किया जाएगा, हालांकि दूसरा वह जो आप विंडो के सेफ एक्सेस पर पहुंच रहे हैं। इसलिए नेविगेशन बार पर विचार नहीं किया जाएगा।
safeAreaLayoutGuide जब दृश्य ऑनस्क्रीन दिखाई देता है, तो यह मार्गदर्शिका दृश्य के उस भाग को दर्शाती है, जो नेविगेशन बार, टैब बार, टूलबार और अन्य पूर्वजों के विचारों द्वारा कवर नहीं किया गया है। (टीवीओएस में, सुरक्षित क्षेत्र स्क्रीन के बेज़ल को कवर नहीं करने वाले क्षेत्र को दर्शाता है।) यदि दृश्य वर्तमान में दृश्य पदानुक्रम में स्थापित नहीं है, या अभी तक ऑनस्क्रीन दिखाई नहीं दे रहा है, तो लेआउट गाइड किनारे दृश्य के किनारों के बराबर हैं।
फिर स्क्रीनशॉट में लाल तीर की ऊंचाई पाने के लिए:
self.safeAreaLayoutGuide.layoutFrame.size.height
स्विफ्ट 5, एक्सकोड 11.4
`UIApplication.shared.keyWindow`
यह डेप्रिसिएशन की चेतावनी देगा। '' keyWindow 'को iOS 13.0 में पदावनत किया गया: इसका उपयोग उन अनुप्रयोगों के लिए नहीं किया जाना चाहिए जो कई दृश्यों का समर्थन करते हैं क्योंकि यह कनेक्टेड दृश्यों की वजह से सभी जुड़े दृश्यों में एक महत्वपूर्ण विंडो देता है। मैं इस तरह का उपयोग करता हूं।
extension UIView {
var safeAreaBottom: CGFloat {
if #available(iOS 11, *) {
if let window = UIApplication.shared.keyWindowInConnectedScenes {
return window.safeAreaInsets.bottom
}
}
return 0
}
var safeAreaTop: CGFloat {
if #available(iOS 11, *) {
if let window = UIApplication.shared.keyWindowInConnectedScenes {
return window.safeAreaInsets.top
}
}
return 0
}
}
extension UIApplication {
var keyWindowInConnectedScenes: UIWindow? {
return windows.first(where: { $0.isKeyWindow })
}
}
ऑब्जेक्टिव-सी कौन समस्या थी जब keyWindow के बराबर है शून्य । बस ऊपर कोड को viewDidAppear में रखें (viewDidLoad में नहीं)
स्विफ्ट 5 एक्सटेंशन
इसे एक्सटेंशन के रूप में इस्तेमाल किया जा सकता है और इसके साथ बुलाया जा सकता है: UIApplication.topSafeAreaHeight
extension UIApplication {
static var topSafeAreaHeight: CGFloat {
var topSafeAreaHeight: CGFloat = 0
if #available(iOS 11.0, *) {
let window = UIApplication.shared.windows[0]
let safeFrame = window.safeAreaLayoutGuide.layoutFrame
topSafeAreaHeight = safeFrame.minY
}
return topSafeAreaHeight
}
}
UIApplication का विस्तार वैकल्पिक है, UIView का विस्तार हो सकता है या जो भी पसंद किया जाता है, या शायद एक वैश्विक फ़ंक्शन भी बेहतर है।
अधिक गोल दृष्टिकोण
import SnapKit
let containerView = UIView()
containerView.backgroundColor = .red
self.view.addSubview(containerView)
containerView.snp.remakeConstraints { (make) -> Void in
make.width.top.equalToSuperView()
make.top.equalTo(self.view.safeArea.top)
make.bottom.equalTo(self.view.safeArea.bottom)
}
extension UIView {
var safeArea: ConstraintBasicAttributesDSL {
if #available(iOS 11.0, *) {
return self.safeAreaLayoutGuide.snp
}
return self.snp
}
var isIphoneX: Bool {
if #available(iOS 11.0, *) {
if topSafeAreaInset > CGFloat(0) {
return true
} else {
return false
}
} else {
return false
}
}
var topSafeAreaInset: CGFloat {
let window = UIApplication.shared.keyWindow
var topPadding: CGFloat = 0
if #available(iOS 11.0, *) {
topPadding = window?.safeAreaInsets.top ?? 0
}
return topPadding
}
var bottomSafeAreaInset: CGFloat {
let window = UIApplication.shared.keyWindow
var bottomPadding: CGFloat = 0
if #available(iOS 11.0, *) {
bottomPadding = window?.safeAreaInsets.bottom ?? 0
}
return bottomPadding
}
}