प्रोग्रामेटिक रूप से नेविगेशन बार की ऊंचाई प्राप्त करें


131

मुझे पता है कि अधिक व्यू कंट्रोलर (नेविगेशन बार) की उपस्थिति इसकी ऊंचाई से UIView को नीचे धकेलती है। मुझे यह भी पता है कि यह ऊंचाई = 44 पीएक्स है। मुझे यह भी पता चला है कि यह धक्का नीचे बनाए रखता है [self.view].frame.origin.y = 0

तो मैं इस नेविगेशन बार की ऊँचाई का निर्धारण कैसे करता हूँ, केवल एक स्थिरांक पर सेट करने के अलावा?

या, छोटा संस्करण, मैं यह कैसे निर्धारित करूं कि मेरा UIView नेविगेशन बार के साथ शीर्ष पर दिखाई दे रहा है?


बिजली का बल्ब आने लगा। दुर्भाग्य से, मैंने समस्या को ठीक करने के लिए एक समान तरीका नहीं खोजा है, जैसा कि नीचे वर्णित है।

मेरा मानना ​​है कि मेरी पूरी समस्या मेरे ऑटोरेस्पोन्डिंग मास्क पर है। और जिस कारण से मैंने निष्कर्ष निकाला है कि एक ही लक्षण मौजूद हैं, एक UIWebView के साथ या उसके बिना। और वह लक्षण यह है कि पोर्ट्रेट के लिए सब कुछ आड़ू है। लैंडस्केप के लिए, नीचे-सबसे यूआईब्यूटॉन टैबबर के पीछे नीचे चबूतरे।

उदाहरण के लिए, एक UIView पर, मेरे पास ऊपर से नीचे तक है:

UIView - दोनों स्प्रिंग्स सेट (डिफ़ॉल्ट केस) और कोई स्ट्रट्स नहीं है

UIScrollView - यदि मैं दो स्प्रिंग्स सेट करता हूं, और बाकी सब कुछ (UIView की तरह) साफ़ करता हूं, तो UIButton इसके ठीक ऊपर वाली वस्तु पर घुसपैठ करता है। अगर मैं सब कुछ साफ कर दूं, तो यूबॉटन ठीक है, लेकिन स्टेटबेर के पीछे बहुत ऊपर छिपा सामान केवल ऊपर की स्ट्रेट को सेट करता है, यूआईब्यूटन टैब बार के पीछे नीचे की ओर पॉप करता है।

UILabel और UIImage अगले लंबवत - शीर्ष अकड़ सेट, हर जगह लचीला

UIWebView वाले कुछ के लिए चित्र को पूरा करने के लिए:

UIWebView - स्ट्रट्स: टॉप, लेफ्ट, राइट स्प्रिंग्स: दोनों

UIButton - हर जगह लचीला, कुछ भी नहीं सेट

यद्यपि मेरा प्रकाश बल्ब मंद है, आशा प्रतीत होती है।


कृपया मेरे साथ रहें क्योंकि मुझे कम उत्तर वाली टिप्पणी के लिए अधिक कमरे की आवश्यकता थी।

समझने की कोशिश करने के लिए धन्यवाद कि मैं वास्तव में मछली पकड़ने के लिए क्या कर रहा हूं ... इसलिए यहां जाता है।

1) प्रत्येक UIViewController (एक TabBar ऐप) में एक UIImage, कुछ पाठ और जो भी शीर्ष पर है। एक अन्य आम भाजक तल पर एक UIButton है। कुछ UIViewControllers पर मेरे पास UIButton के ऊपर UIWebView है।

तो, UIImage, पाठ आदि UIWebView (कुछ पर) UIButton

उपरोक्त सभी को घेरना एक UIScrollView है।

2) उन लोगों के लिए जिनके पास UIWebView है, इसका ऑटोरेस्पोन्गिंग मास्क जैसा दिखता है:

   
   |
   

   ^
   |
   |

| - | - ---- → | - | | | V UIButton के मास्क में कुछ भी नहीं है, अर्थात, हर जगह लचीला

मेरे -व्यूडीडलड के भीतर, मैं अपने -repositionSubViews को कॉल करता हूं जिसके भीतर मैं निम्नलिखित कार्य करता हूं:

अगर कोई UIWebView नहीं है, तो मैं UIButton को केंद्र में रखने के अलावा कुछ नहीं करता, जिसे मैंने IB के साथ रखा था।

अगर मेरे पास UIWebView है, तो मैं इसकी * सामग्री * ऊंचाई निर्धारित करता हूं और इसकी फ़्रेम को पूरी सामग्री को संलग्न करने के लिए निर्धारित करता हूं।

UIScrollView *scrollViewInsideWebView = [[webView_ subviews] lastObject];
webViewContentHeight = scrollViewInsideWebView.contentSize.height;
[webView_ setFrame:CGRectMake(webViewOriginX, webViewOriginY,
                          sameWholeViewScrollerWidth, webViewContentHeight)]

एक बार जब मैं ऐसा कर लेता हूं, तो मैं प्रोग्रामेटिक रूप से यूआईबूटन को नीचे धकेल देता हूं ताकि वह यूआईब्यूव्यू के नीचे रखा जाए।

सब कुछ काम करता है, जब तक कि मैं इसे पोर्ट्रेट से लैंडस्केप तक नहीं घुमाता।

मैं -didRotateFromInterfaceOrientation में अपने -repositionSubViews को कॉल करता हूं।

मेरे UIWebView की सामग्री ऊंचाई रोटेशन के साथ क्यों नहीं बदलती है?

पोर्ट्रेट से लैंडस्केप तक, सामग्री की चौड़ाई का विस्तार होना चाहिए और सामग्री की ऊंचाई को छोटा करना चाहिए। यह नेत्रहीन रूप से इसे करना चाहिए, लेकिन मेरे NSLog के अनुसार नहीं।

वैसे भी, UIWebView के साथ या उसके बिना, बटन जब मैंने लैंडस्केप मोड में टैबबार के नीचे ले जाने के बारे में बात की है, लेकिन इसे देखने के लिए स्क्रॉल नहीं किया जाएगा। मैं इसे TabBar के पीछे देखता हूं जब मैं "सख्ती" स्क्रॉल करता हूं, लेकिन तब यह TabBar के पीछे "वापस गिर जाता है"।

निचला रेखा, यह अंतिम कारण है कि मैंने TabBar और नेविगेशनबार की ऊंचाई के बारे में पूछा है क्योंकि TabBar अपने आप को UIView के निचले भाग में स्थित करता है और नेविगेशनबार UIView को नीचे धकेलता है।

अब, मैं एक टिप्पणी या दो को यहाँ जोड़ने जा रहा हूँ क्योंकि वे पहले से समझ में नहीं आते।

UIWebView के बिना, मैं सब कुछ छोड़ देता हूं, जैसा कि आईबी द्वारा देखा गया है।

UIWebView के साथ, मैं UIWebView के फ्रेम को बढ़ाता हूं। इसके contentHeight को बढ़ाता हूं और आसपास के UIScrollView की ऊंचाई को भी समायोजित करता है जो सभी उप-विचारों को घेरता है।

खैर, यह लो।

जवाबों:


258

कुछ ऐसा करो?

    NSLog(@"Navframe Height=%f",
        self.navigationController.navigationBar.frame.size.height);

स्विफ्ट संस्करण यहां स्थित है


अपडेट करें

iOS 13

जैसा कि आप में उपयोग statusBarFrameकिया गया था , इसका iOS13उपयोग किया गया था :

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

शुक्रिया शुक्रिया। लेकिन, अब जब आपने उस समस्या को हल कर लिया है, तो मैं यह कैसे निर्धारित करूँ कि अगर नेविगेशनकंट्रोलर, उर्फ, MoreViewController, मेरे टैब बार ऐप के लिए प्रदर्शित हो रहा है।

मुझे वह नहीं मिला जो आप कहना चाह रहे हैं। क्या आप यह जानने की कोशिश कर रहे हैं कि MoreViewController क्या दिखा रहा है? (यदि हां, तो आप क्या करना चाहते हैं?) और यदि नहीं, तो क्या आप स्पष्ट कर सकते हैं कि वास्तव में आपका क्या मतलब है?
सम

मैंने आपका प्रश्न फिर से पढ़ा, और मुझे अभी तक समझ नहीं आया कि आप क्या करना चाहते हैं? यदि आप दृश्य दिखाई देने पर कुछ करना चाहते हैं, तो आपको कोड को viewDidAppear में सम्मिलित करना चाहिए। यदि आप थोड़ा स्पष्ट करते हैं, तो यह पता लगाना आसान होगा कि आप क्या करना चाहते हैं।
सूम

2
मुझे पता है कि यह उस सवाल को संबोधित नहीं करता है जो उसने पूछा था, लेकिन ऐसा लगता है कि वह यह देखना चाह रहा था कि नेविगेशनबार छिपा हुआ था या नहीं। यदि ऐसा है, तो वह self.navigationController.navigationBarHidden का उपयोग कर सकता था। आशा है कि यह पूरी तरह से किसी की मदद करता है :)
taylorcressy

2
IOS 7+ में आपको अपने आवेदन के आधार पर 20px स्टेटस बार पर भी विचार करने की आवश्यकता हो सकती है
Slayter

94

IPhone-X के साथ, शीर्ष बार (नेविगेशन बार + स्थिति पट्टी) की ऊंचाई बदल जाती है (बढ़ जाती है)।

यदि आप शीर्ष बार की सटीक ऊंचाई चाहते हैं तो यह कोशिश करें (दोनों नेविगेशन बार + स्थिति बार):

अपडेट करें

iOS 13

जैसा कि आप में उपयोग statusBarFrameकिया गया था , इसका iOS13उपयोग किया गया था :

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

उद्देश्य सी

CGFloat topbarHeight = ([UIApplication sharedApplication].statusBarFrame.size.height +
       (self.navigationController.navigationBar.frame.size.height ?: 0.0));

स्विफ्ट 4

let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
        (self.navigationController?.navigationBar.frame.height ?? 0.0)

आसानी के लिए, इस UIViewController एक्सटेंशन का प्रयास करें

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

स्विफ्ट 3

let topBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)


3
स्विफ्ट 4 का उत्तर मेरे लिए 0 की ऊँचाई देता है।
Chewie द कोरकी

61

स्विफ्ट संस्करण:

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height

हमेशा ४४ देता है। ढह चुके आकार (४४) या विस्तारित आकार (बड़े शीर्षक) को कैसे जानें ??? निश्चित रूप से, निश्चित रूप से। (मुझे पता है कि यह क्या उपाय करता है)
मार्कस

6

क्या आपने यह कोशिश की?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0

5

समर्थन iOS 13 और नीचे:

extension UIViewController {

    var topbarHeight: CGFloat {
        if #available(iOS 13.0, *) {
            return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
                (self.navigationController?.navigationBar.frame.height ?? 0.0)
        } else {
            let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
            return topBarHeight
        }
    }
}

4
UIImage*image = [UIImage imageNamed:@"logo"];

float targetHeight = self.navigationController.navigationBar.frame.size.height;
float logoRatio = image.size.width / image.size.height;
float targetWidth = targetHeight * logoRatio;

UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
// X or Y position can not be manipulated because autolayout handles positions.
//[logoView setFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width - targetWidth) / 2 , (self.navigationController.navigationBar.frame.size.height - targetHeight) / 2 , targetWidth, targetHeight)];
[logoView setFrame:CGRectMake(0, 0, targetWidth, targetHeight)];
self.navigationItem.titleView = logoView;

// How much you pull out the strings and struts, with autolayout, your image will fill the width on navigation bar. So setting only height and content mode is enough/
[logoView setContentMode:UIViewContentModeScaleAspectFit];

/* Autolayout constraints also can not be manipulated since navigation bar has  immutable constraints
self.navigationItem.titleView.translatesAutoresizingMaskIntoConstraints = false;

NSDictionary*metricsArray = @{@"width":[NSNumber numberWithFloat:targetWidth],@"height":[NSNumber numberWithFloat:targetHeight],@"margin":[NSNumber numberWithFloat:20]};
NSDictionary*viewsArray = @{@"titleView":self.navigationItem.titleView};

[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>margin=)-H:[titleView(width)]-(>margin=)-|" options:NSLayoutFormatAlignAllCenterX metrics:metricsArray views:viewsArray]];
[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[titleView(height)]" options:0 metrics:metricsArray views:viewsArray]];

NSLog(@"%f", self.navigationItem.titleView.width );
*/

इसलिए हम सभी को वास्तव में जरूरत है

UIImage*image = [UIImage imageNamed:@"logo"];
UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
float targetHeight = self.navigationController.navigationBar.frame.size.height;
[logoView setFrame:CGRectMake(0, 0, 0, targetHeight)];
[logoView setContentMode:UIViewContentModeScaleAspectFit];

self.navigationItem.titleView = logoView;

2

मेरे आवेदन में कुछ ऐसे दृश्य हैं, जिन्हें देखने और महसूस करने के लिए UI में एक अनुकूलित नेविगेशन बार की आवश्यकता है, हालांकि नेविगेशन नियंत्रक के बिना। और आईओएस 11 से पहले आईओएस संस्करण का समर्थन करने के लिए एप्लिकेशन की आवश्यकता होती है, इसलिए आसान सुरक्षित क्षेत्र लेआउट गाइड का उपयोग नहीं किया जा सकता है, और मुझे प्रोग्राम बार की स्थिति और ऊंचाई को समायोजित करना होगा।

जैसा कि ऊपर उल्लेख किया गया है, मैंने सुरक्षित क्षेत्र लेआउट गाइड को छोड़ते हुए सीधे नेविगेशन बार को इसके सुपरवाइज से जोड़ा। और स्थिति बार ऊंचाई आसानी से UIApplication से पुनर्प्राप्त की जा सकती है, लेकिन डिफ़ॉल्ट नेविगेशन बार ऊंचाई वास्तव में दर्द-गधा है ...

इसने मुझे लगभग आधी रात तक, कई खोज और परीक्षण के साथ मारा, जब तक कि मुझे अंत में किसी अन्य पद से संकेत नहीं मिला (हालांकि मुझे काम नहीं करना चाहिए), कि आप वास्तव में UIView.sizeThatFits () से ऊंचाई प्राप्त कर सकते हैं, इस तरह :

- (void)viewWillLayoutSubviews {
    self.topBarHeightConstraint.constant = [UIApplication sharedApplication].statusBarFrame.size.height;
    self.navBarHeightConstraint.constant = [self.navigationBar sizeThatFits:CGSizeZero].height;

    [super viewWillLayoutSubviews];    
}

अंत में, एक परफेक्ट नेविगेशन बार बिल्ट-इन एक जैसा ही दिखता है!


2

यदि आप navigationBarकेवल ऊँचाई प्राप्त करना चाहते हैं , तो यह सरल है:

extension UIViewController{
   var navigationBarHeight: CGFloat {
       return self.navigationController?.navigationBar.frame.height ?? 0.0
   }
}

हालाँकि, यदि आपको iPhone के शीर्ष पायदान की ऊंचाई की आवश्यकता है, तो आपको ऊँचाई प्राप्त करने navigationBarऔर इसे statusBarऊँचाई में जोड़ने की आवश्यकता नहीं है , आप बस कॉल कर सकते हैं, safeAreaInsetsइसलिए मौजूद है।

self.view.safeAreaInsets.top

1

बिजली का बल्ब आने लगा। दुर्भाग्य से, मैंने समस्या को ठीक करने के लिए एक समान तरीका नहीं खोजा है, जैसा कि नीचे वर्णित है।

मेरा मानना ​​है कि मेरी पूरी समस्या मेरे ऑटोरेस्पोन्डिंग मास्क पर है। और जिस कारण से मैंने निष्कर्ष निकाला है कि एक ही लक्षण मौजूद हैं, एक UIWebView के साथ या उसके बिना। और वह लक्षण यह है कि पोर्ट्रेट के लिए सब कुछ आड़ू है। लैंडस्केप के लिए, नीचे-सबसे यूआईब्यूटॉन टैबबर के पीछे नीचे चबूतरे।

उदाहरण के लिए, एक UIView पर, मेरे पास ऊपर से नीचे तक है:

UIView - दोनों स्प्रिंग्स सेट (डिफ़ॉल्ट केस) और कोई स्ट्रट्स नहीं है

UIScrollView - यदि मैं दो स्प्रिंग्स सेट करता हूं, और बाकी सब कुछ (UIView की तरह) साफ़ करता हूं, तो UIButton इसके ठीक ऊपर वाली वस्तु पर घुसपैठ करता है। अगर मैं सब कुछ साफ कर दूं, तो यूबॉटन ठीक है, लेकिन स्टेटबेर के पीछे बहुत ऊपर छिपा सामान केवल ऊपर की स्ट्रेट को सेट करता है, यूआईब्यूटन टैब बार के पीछे नीचे की ओर पॉप करता है।

UILabel और UIImage अगले लंबवत - शीर्ष अकड़ सेट, हर जगह लचीला

UIWebView वाले कुछ के लिए चित्र को पूरा करने के लिए:

UIWebView - स्ट्रट्स: टॉप, लेफ्ट, राइट स्प्रिंग्स: दोनों

UIButton - हर जगह लचीला, कुछ भी नहीं सेट

यद्यपि मेरा प्रकाश बल्ब मंद है, आशा प्रतीत होती है।


शीर्ष अकड़ सेट करें और UIWebView के दो स्प्रिंग्स सेट करें - समस्या हल और धन्यवाद बंच। तथ्य की बात के रूप में, मेरी एकमात्र शेष समस्या उन शापित @ 2X, आदि ग्राफिक्स को डिजाइन करना है। मैं बहुत ही सरल तरीके से GraphicConverter का उपयोग करता हूं और यह वेब पेज डिज़ाइन के लिए बहुत अच्छी तरह से करता है। लेकिन इन सभी 30px, 57px सामान - मैं कम से कम मेरे लिए अपरिवर्तित क्षेत्र में जा रहा हूं।

1

यहाँ आपके अपडेट के लिए मेरी प्रतिक्रिया की शुरुआत है:

मेरे UIWebView की सामग्री ऊंचाई रोटेशन के साथ क्यों नहीं बदलती है?

क्या ऐसा हो सकता है क्योंकि आपके ऑटो का आकार सभी दिशाओं के लिए ऑटोरेस्पोन्गिंग मास्क नहीं है?

एक और सुझाव इससे पहले कि मैं इसके लिए वापस आऊं, क्या आप अपनी जरूरतों के लिए टूलबार का उपयोग कर सकते हैं। यह थोड़ा सरल है, हमेशा नीचे, ऑटो-रोटेट / पदों पर रहेगा। आप इसे अपनी इच्छानुसार छुपा सकते हैं / दिखा सकते हैं। इस तरह की: http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

आप उस विकल्प को देख सकते हैं, लेकिन इसे वहां फेंक सकते हैं।

एक अन्य विचार, क्या आप संभवतः पता लगा सकते हैं कि आप किस अभिविन्यास से घूम रहे हैं, और टैब बार के लिए समायोजित करने के लिए बस बटन को प्रोग्रामेटिक रूप से रखें। (यह कोड के साथ संभव है)


इससे निपटने के बारे में 2 सप्ताह के बाद, मैंने फैसला किया कि "समस्या" को यूआईब्यूटॉन की तुलना में UIWebView उप-दृश्य रखकर अधिक कठिन बना दिया गया था। इसलिए, मैंने बटन ABOVE डाल दिया। स्पष्ट रूप से, यह सिर्फ उस तरह से "सही" नहीं दिखता है ... लेकिन यह अब SORT OF काम करता है। कम या अधिक UIWebView ने शीर्ष अकड़ और सिर्फ क्षैतिज वसंत निर्धारित किया है। BTW, इसके UIHebView की सामग्रीहाइट जो रोटेशन के साथ नहीं बदलती है।

0

मैंने उपयोग कर लिया है:

let originY: CGFloat = self.navigationController!.navigationBar.frame.maxY

यदि आप नेविगेशन बार ऊंचाई और इसके वाई मूल को प्राप्त करना चाहते हैं तो बढ़िया काम करना।



0

आसान स्विफ्ट 4 एक्सटेंशन, यदि यह किसी और के लिए सहायक है। भले ही वर्तमान दृश्य नियंत्रक एक नेविगेशन बार प्रदर्शित नहीं करता है।

import UIKit

extension UINavigationController {
  static public func navBarHeight() -> CGFloat {
    let nVc = UINavigationController(rootViewController: UIViewController(nibName: nil, bundle: nil))
    let navBarHeight = nVc.navigationBar.frame.size.height
    return navBarHeight
  }
}

उपयोग:

UINavigationController.navBarHeight()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.