Programlı olarak gezinme çubuğunun yüksekliğini alın


131

Daha fazla görüntüleme denetleyicisinin (gezinme çubuğu) varlığının, UIView'ı yüksekliği ile aşağıya ittiğini biliyorum. Ayrıca bu yüksekliğin 44px olduğunu da biliyorum. Ayrıca, bu aşağı itmenin [self.view].frame.origin.y = 0.

Öyleyse, bu gezinme çubuğunun yüksekliğini sabit olarak ayarlamak dışında nasıl belirleyebilirim?

Veya, daha kısa sürüm, UIView'umun üstte gezinme çubuğu ile gösterildiğini nasıl belirleyebilirim?


Ampul yanmaya başladı. Maalesef, aşağıda açıklandığı gibi sorunu düzeltmenin tek tip bir yolunu bulamadım.

Tüm sorunumun otomatik yeniden boyutlandırma maskelerime odaklandığını düşünüyorum. Ve UIWebView ile veya onsuz aynı semptomların var olduğu sonucuna varmamın nedeni. Ve bu belirti, Portre için her şeyin şeftali gibi olmasıdır. Yatay için, en alttaki UIButton, TabBar'ın arkasında açılır.

Örneğin, bir UIView'de yukarıdan aşağıya:

UIView - her iki yay da ayarlanmış (varsayılan durum) ve destek yok

UIScrollView - İki yayı ayarlarsam ve diğer her şeyi temizlersem (UIView gibi), UIButton hemen üstündeki nesneye girer. Her şeyi temizlersem, UIButton tamamdır, ancak en üstteki şeyler StatusBar Ayarının arkasına gizlenir, sadece üst dikme, UIButton Sekme Çubuğunun arkasına açılır.

Sıradaki UILabel ve UIImage dikey olarak - üst destek seti, her yerde esnek

Sadece UIWebView olan birkaç kişi için resmi tamamlamak için:

UIWebView - Dikmeler: üst, sol, sağ Yaylar: ikisi de

UIButton - hiçbir şey ayarlanmadı, yani her yerde esnek

Ampulüm sönük olsa da umut var gibi görünüyor.


Lütfen bana katlanın çünkü kısa bir cevap yorumu için sağlanandan daha fazla alana ihtiyacım vardı.

Gerçekten ne için balık tuttuğumu anlamaya çalıştığın için teşekkürler ... işte burada.

1) Her UIViewController (bir TabBar uygulaması) bir UIImage, bir miktar metin ve üstte ne varsa içerir. Diğer bir ortak payda, alttaki UIB düğmesidir. Bazı UIViewControllers üzerinde UIButton üzerinde bir UIWebView var.

Yani, UIImage, metin vb. UIWebView (BAZILARI üzerinde) UIB düğmesi

Yukarıdakilerin tümünü çevreleyen bir UIScrollView'dur.

2) UIWebView'a sahip olanlar için, autoresizingMask şöyle görünür:

   
   |
   

   ^
   |
   |

| - | ← ---- → | - | | | V UIButton'un maskesinde hiçbir şey ayarlanmamış, yani her yerde esnek

-ViewDidLoad'um içinde, içinde aşağıdakileri yaptığım -repositionSubViews adını veriyorum:

UIWebView yoksa, IB'ye yerleştirdiğim UIButton'u ortalamak dışında hiçbir şey yapmam.

Bir UIWebView'a sahipsem, * içerik * Yüksekliğini belirlerim ve çerçevesini tüm içeriği kapsayacak şekilde ayarlarım.

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

Bunu yaptıktan sonra, UIButton'u programlı olarak aşağı iterek UIWebView'in altına yerleştirilmesini sağlarım.

Dikeyden Yatay'a döndürene kadar her şey çalışıyor.

-DidRotateFromInterfaceOrientation içinde -repositionSubViews adını veriyorum.

UIWebView'umun içerik yüksekliği neden rotasyonla değişmiyor ?.

Dikeyden Yatay'a, içerik genişliği genişlemeli ve içerik yüksekliği küçülmelidir. Olması gerektiği gibi görsel olarak çalışıyor, ancak NSLog'uma göre değil.

Her neyse, bir UIWebView olsun veya olmasın, bahsettiğim düğme Yatay moddayken TabBar'ın altına hareket ediyor, ancak görülmek için yukarı kaydırılmayacak. "Şiddetle" kaydırdığımda TabBar'ın arkasında görüyorum ama sonra TabBar'ın arkasına "geri dönüyor".

Sonuç olarak, bu sonuncusu TabBar ve NavigationBar'ın yüksekliğini sormamın nedenidir çünkü TabBar kendisini UIView'ın altına yerleştirir ve NavigationBar UIView'ı aşağı iter.

Şimdi, buraya bir veya iki yorum ekleyeceğim çünkü daha önce mantıklı olmazlardı.

UIWebView olmadan, her şeyi IB tarafından görüldüğü gibi bırakıyorum.

Bir UIWebView ile, UIWebView'ün frame.height'ını contentHeight'a yükseltiyorum ve ayrıca tüm alt görünümleri çevreleyen çevreleyen UIScrollView'ın yüksekliğini yukarı doğru ayarlıyorum.

İşte orada var.

Yanıtlar:


258

Böyle bir şey mi yapıyorsun?

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

Hızlı versiyon burada bulunur


GÜNCELLEME

iOS 13

Gibi statusBarFramekullanımdan kaldırıldı iOS13Bunu kullanabilirsiniz:

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)
    }
}

Teşekkür ederim teşekkür ederim. AMA, şimdi bu sorunu çözdüğünüze göre, NavigationController'ın, yani MoreViewController'ın sekme çubuğu uygulamam için gösterilip gösterilmediğini nasıl belirleyeceğim.

Ne söylemeye çalıştığını tam olarak anlayamıyorum. MoreViewController'ın gösterip göstermediğini anlamaya mı çalışıyorsunuz? (Öyleyse, ne yapmak istiyorsun?) Ve eğer istemiyorsan, tam olarak ne demek istediğini açıklayabilir misin?
Toplam

Sorunuzu tekrar okudum ve hala ne yapmak istediğinizi anlamadım. Görünüm göründüğünde bir şey yapmak istiyorsanız, kodu viewDidAppear'a eklemelisiniz. Biraz netleştirirseniz, ne yapmak istediğinizi belirlemenizi kolaylaştırır.
Toplam

2
Bunun sorduğu soruyu ele almadığını biliyorum, ancak gezinme çubuğunun gizli olup olmadığını görmek istiyormuş gibi görünüyor. Eğer öyleyse, self.navigationController.navigationBarHidden Hope'u kullanabilirdi, bu tamamen birine yardımcı olur :)
taylorcressy

2
İOS 7+ sürümünde, uygulamanıza bağlı olarak 20px durum çubuğunu da göz önünde bulundurmanız gerekebilir
Slayter

94

İPhone-X ile üst çubuğun (gezinme çubuğu + durum çubuğu) yüksekliği değiştirilir (artırılır).

Üst çubuğun tam yüksekliğini istiyorsanız bunu deneyin (hem gezinme çubuğu + durum çubuğu):

GÜNCELLEME

iOS 13

Gibi statusBarFramekullanımdan kaldırıldı iOS13Bunu kullanabilirsiniz:

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)
    }
}

Objective-C

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

Swift 4

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

Kolaylık için bu UIViewController uzantısını deneyin

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)
    }
}

Hızlı 3

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


3
Swift 4 cevabı benim için 0 yükseklik döndürüyor.
Chewie The Chorkie

61

Swift versiyonu:

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

Her zaman 44 döndürür. Daraltılmış boyut (44) veya genişletilmiş boyut (büyük başlıklar) nasıl anlaşılır ??? Tabii ki dinamik olarak. (Ne ölçtüğünü biliyorum)
Markus

6

Bunu denedin mi

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

5

İOS 13 ve Altını Destekleyin:

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 );
*/

Yani aslında ihtiyacımız olan tek şey

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

Uygulamam, görünüm ve his için kullanıcı arayüzünde özelleştirilmiş bir gezinme çubuğu gerektiren, ancak gezinme denetleyicisi olmayan bir çift görünüme sahip. Ve uygulamanın iOS 11'den önceki iOS sürümünü desteklemesi gerekiyor, bu nedenle kullanışlı güvenli alan yerleşim kılavuzu kullanılamıyor ve gezinme çubuğunun konumunu ve yüksekliğini programlı olarak ayarlamam gerekiyor.

Gezinme Çubuğunu, yukarıda belirtildiği gibi güvenli alan yerleşim kılavuzunu atlayarak doğrudan gözetim görünümüne ekledim. Ve durum çubuğu yüksekliği UIApplication'dan kolayca alınabilir, ancak varsayılan gezinme çubuğu yüksekliği gerçekten can sıkıcı ...

Neredeyse yarım gece boyunca, bir dizi arama ve testle, sonunda başka bir gönderiden (benim için çalışmıyor) ipucunu alana kadar, UIView.sizeThatFits () 'den yüksekliği alabileceğime dair ipucu aldı. :

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

    [super viewWillLayoutSubviews];    
}

Son olarak, yerleşik olanla tamamen aynı görünen mükemmel bir gezinme çubuğu!


2

navigationBarYalnızca yüksekliği almak istiyorsanız , çok basit:

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

Bununla birlikte, iPhone'un en üst çentik yüksekliğine ihtiyacınız varsa, yüksekliği almanız navigationBarve ona statusBaryüksekliği eklemeniz gerekmez safeAreaInsets, bu yüzden varolduğunu söyleyebilirsiniz .

self.view.safeAreaInsets.top

1

Ampul yanmaya başladı. Ne yazık ki, aşağıda açıklandığı gibi sorunu düzeltmenin tek tip bir yolunu bulamadım.

Tüm sorunumun otomatik yeniden boyutlandırma maskelerime odaklandığına inanıyorum. Ve UIWebView ile veya onsuz aynı semptomların var olduğu sonucuna varmamın nedeni. Ve bu belirti, Portre için her şeyin şeftali gibi olmasıdır. Yatay için, en alttaki UIButton, TabBar'ın arkasında açılır.

Örneğin, bir UIView'de yukarıdan aşağıya:

UIView - her iki yay da ayarlanmış (varsayılan durum) ve destek yok

UIScrollView - İki yayı ayarlarsam ve diğer her şeyi temizlersem (UIView gibi), UIButton hemen üstündeki nesneye girer. Her şeyi temizlersem, UIButton tamamdır, ancak en üstteki şeyler StatusBar Ayarının arkasına gizlenir, sadece üst dikme, UIButton Sekme Çubuğunun arkasına açılır.

Sıradaki UILabel ve UIImage dikey olarak - üst destek seti, her yerde esnek

Sadece UIWebView olan birkaç kişi için resmi tamamlamak için:

UIWebView - Dikmeler: üst, sol, sağ Yaylar: ikisi de

UIButton - hiçbir şey ayarlanmadı, yani her yerde esnek

Ampulüm sönük olsa da umut var gibi görünüyor.


Üst desteği ayarlayın ve UIWebView'ın iki yayını ayarlayın - sorun çözüldü ve teşekkürler. Nitekim geriye kalan tek sorunum @ 2X vb. Lanetli grafikleri tasarlamak. GraphicConverter'ı çok basit bir şekilde kullanıyorum ve Web Sayfası tasarımı için çok iyi. Ama tüm bu 30px, 57px şeyler - En azından benim için keşfedilmemiş bir bölgeye gidiyorum.

1

İşte güncellemenize cevabımın başlangıcı:

UIWebView'umun içerik yüksekliği neden rotasyonla değişmiyor ?.

Otomatik yeniden boyutlandırmanızın tüm yönler için otomatik yeniden boyutlandırma maskesine sahip olmaması olabilir mi?

Bunun için geri gelmeden önce başka bir öneri, ihtiyaçlarınız için bir araç çubuğu kullanabilir misiniz? Biraz daha basit, her zaman altta olacak, otomatik döndürme / konumlandırma. İstediğiniz zaman gizleyebilir / gösterebilirsiniz. Bunun gibi: http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

O seçeneğe bakmış olabilirsiniz, ama sadece oraya atıyorsunuz.

Başka bir fikir, muhtemelen hangi yönden döndüğünüzü tespit edebilir ve sekme çubuğunu ayarlamak için düğmeyi programlı olarak yerleştirebilir misiniz? (Bu kodla mümkündür)


Bunun üstesinden geldikten yaklaşık 2 hafta sonra, UIWebView alt görünümünün AŞAĞIDA bir UIB düğmesi yerleştirerek "sorunun" daha zor hale geldiğine karar verdim. Bu yüzden düğmeyi ÜSTÜNE koyuyorum. Açıkçası, bu şekilde "doğru" görünmüyor ... ama şimdi SORT OF çalışıyor. UIWebView AŞAĞIDA veya ÜZERİNDE üst gergiyi ve sadece yatay yayı ayarladı. BTW, UIWebView'in rotasyonla değişmeyen contentHeight değeridir.

0

Kullandım:

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

Gezinme çubuğunun yüksekliğini VE Y başlangıcını almak istiyorsanız harika çalışıyor.


0

Swift 5

SafeArea'yı da düşünmek istiyorsanız:

 let height = navigationController?.navigationBar.frame.maxY  

0

Kullanışlı Swift 4 uzantısı, bir başkasına yardımcı olması durumunda. Geçerli görünüm denetleyicisi bir gezinme çubuğu görüntülemese bile çalışır.

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
  }
}

Kullanımı:

UINavigationController.navBarHeight()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.