Durum çubuğu ve gezinme çubuğu, iOS 7'deki görünümümün sınırları üzerinde görünüyor


435

Kısa bir süre önce Xcode 5 DP'yi iOS 7'de uygulamaları test etmek için indirdim. Fark ettiğim ve onayladığım ilk şey, görünümümün sınırlarının her zaman durum çubuğu ve gezinme çubuğunu hesaba katmak için yeniden boyutlandırılmamış olmasıdır.

İçinde viewDidLayoutSubviews, görünümün sınırlarını yazdırıyorum:

{{0, 0}, {320, 568}}

Bu, içeriğimin gezinme çubuğunun ve durum çubuğunun altında görünmesine neden olur.

Ana ekranın yüksekliğini alarak, durum çubuğunun yüksekliğini ve gezinme çubuğunun yüksekliğini çıkararak yüksekliği kendim hesaplayabileceğimi biliyorum, ancak bu gereksiz ekstra iş gibi görünüyor.

Bu sorunu nasıl düzeltebilirim?

Güncelleme:

Bu sorun için bir çözüm buldum. Gezinme çubuğunun yarı saydam özelliğini NO olarak ayarlayın:

self.navigationController.navigationBar.translucent = NO;

Bu, görünümün gezinme çubuğunun ve durum çubuğunun altında çerçevelenmesini düzeltir.

Ancak, gezinme çubuğunun yarı saydam olmasını istediğinizde durum için bir düzeltme bulamadım. Örneğin, bir fotoğrafı tam ekran görüntülerken, gezinme çubuğunun yarı saydam olmasını ve görünümün altında çerçevelenmesini istiyorum. Bu işe yarıyor, ancak gezinme çubuğunu göstermeyi / gizlemeyi değiştirdiğimde daha da garip sonuçlar elde ettim. İlk alt görünüm (bir UIScrollView), kökeni her seferinde değiştirir.


Aynı sorunu xcode 5 DP de alıyorum
Gopesh Gupta

Biraz çözüm
alacaksanız

1
Renk tonu özelliği için gezinme çubuğuna bakın, bu mavi rengi istediğiniz gibi değiştirebilirsiniz.
beebcon

9
Apple'ın uygulamanızı geriye dönük olarak uyumlu tutması için asla bir fırsat vermediği için bazen ios yükseltmesinden nefret ediyorum.
Bagusflyer

3
Sorun, gezinti denetleyicisi üst çubuğunu gizledikten sonra durum çubuğunun altına giren görünümle ilgiliyse , çözüm olarak @Stunner stackoverflow.com/a/18976660/235206 tarafından verilen cevaba
14'te MiKL

Yanıtlar:


495

Bunu, edgesForExtendedLayoutiOS7 SDK olarak adlandırılan yeni bir özellik uygulayarak başarabilirsiniz . Bunu başarmak için lütfen aşağıdaki kodu ekleyin,

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

Yukarıdaki -(void)viewDidLoadyöntemi yönteminize eklemeniz gerekir .

iOS 7, kullanıcı arayüzünüzün görünümünü nasıl düzenlediğinize ve özelleştirdiğinize dair bazı değişiklikler getirir . Görünüm denetleyicisi düzeninde, renk tonunda ve yazı tipindeki değişiklikler uygulamanızdaki tüm UIKit nesnelerini etkiler . Ayrıca, hareket tanıma API'larındaki geliştirmeler, hareket etkileşimleri üzerinde daha hassas bir kontrol sağlar.

Görünüm Denetleyicilerini Kullanma

İOS 7'de görünüm denetleyicileri tam ekran düzeni kullanır. Aynı zamanda, iOS 7, bir görünüm denetleyicisinin görünümlerini düzenleme şekli üzerinde size daha ayrıntılı bir kontrol sağlar. Özellikle, tam ekran düzeni kavramı, bir görünüm denetleyicisinin görünümünün her bir kenarının düzenini belirtmesine izin verecek şekilde rafine edilmiştir.

wantsFullScreenLayoutŞu anda belirtirseniz görünümü denetleyicisi özelliği iOS 7'de önerilmiyor wantsFullScreenLayout = NOo iOS 7'de çalıştırıldığında, görünüm denetleyicisi beklenmedik bir ekran yerde içeriğini görüntüleyebilir.

Bir görünüm denetleyicisinin görünümlerini nasıl UIViewController düzenleyeceğini ayarlamak için aşağıdaki özellikleri sağlar:

  • edgesForExtendedLayout

edgesForExtendedLayoutÖzelliği kullanan UIRectEdgehiçbiri ve belirten ek olarak, bir dikdörtgenin dört kenarlarının her belirtir türü. edgesForExtendedLayoutÇubuk saydamlığına bakılmaksızın bir görünümün hangi kenarlarının genişletilmesi gerektiğini belirtmek için kullanın . Varsayılan olarak, bu özelliğin değeri UIRectEdgeAll.

  • extendedLayoutIncludesOpaqueBars

Tasarımınız opak çubuklar kullanıyorsa edgesForExtendedLayout, extendedLayoutIncludesOpaqueBarsözelliği HAYIR olarak ayarlayarak daraltın . (Varsayılan değeri extendedLayoutIncludesOpaqueBarsolan NO .)

  • automaticallyAdjustsScrollViewInsets

Eğer istemiyorsanız bir kaydırma görünümün içerik insets otomatik seti ayarlanması automaticallyAdjustsScrollViewInsetsiçin NO . (Varsayılan değeri automaticallyAdjustsScrollViewInsetsolan EVET .)

  • topLayoutGuide, altLayoutGuide

topLayoutGuideVe bottomLayoutGuideözellikleri, bir görünüşüdür denetleyicisinin görünümünde üst ya da alt çubuk kenarlarının konumunu göstermektedir. Çubuklar bir görünümün üst veya alt topLayoutGuidekısmıyla çakışıyorsa, Arayüz Oluşturucu'yu , altLayoutGuide öğesinin altına veya üstüne sınırlamalar oluşturarak görünümü çubuğa göre konumlandırmak için kullanabilirsiniz. (Hiçbir çubuk topLayoutGuidegörünümün üstüne bottomLayoutGuidebinmezse, alt kısmı görünümün üstüyle ve üst kısmı görünümün altıyla aynıdır.) İstendiğinde her iki özellik de tembel olarak oluşturulur.

Lütfen bakın, apple doc


2
İOS6 altında derlenmez. Bence
icracı

8
Evet, Thats ile seçici çek dahil ettik neden koşulu, eğer varsa ([öz respondsToSelector: @selector (edgesForExtendedLayout)])
Nandha

19
Gezinme çubuğum yoksa bu çalışmaz. Bu durumda, görüşüm durum çubuğunun arkasına uzanıyor ..
Van Du Tran

4
@VanDuTran ile aynı sorunum var. Gezinme çubuğu gizlenmişse edgeForExtendedLayout yardımcı olmaz.
fishinear

6
işe yarıyor ama ... artık yarı saydam bir etki yok ... yarı saydam efekti nasıl koruyabiliriz ...
Dipu Rajak

110

Her şeyi ne kadar aşağı kaydıracağınızı hesaplamanıza gerek yok, bunun için bir özellik var. Arayüz Oluşturucu'da, görünüm denetleyicinizi vurgulayın ve ardından özellikler denetçisine gidin. Burada "Kenarları Uzat" kelimelerinin yanında bazı onay kutuları göreceksiniz. Gördüğünüz gibi, ilk ekran görüntüsünde varsayılan seçim, içeriğin üst ve alt çubukların altında görünmesi, ancak opak çubukların altında görünmemesidir, bu yüzden çubuk stilini sizin için yarı saydam olmayacak şekilde ayarlamak sizin için çalıştı.

İlk ekran görüntüsünde biraz görebileceğiniz gibi, gezinme çubuğunun altında saklanan iki UI öğesi var. (Bunu göstermek için IB'de tel kafesleri etkinleştirdim) Bir UIButton ve bir UISegmentedControl öğelerinin her ikisi de "y" kaynağını sıfıra ayarladı ve görünüm denetleyicisi, üst çubuğun altındaki içeriğe izin verecek şekilde ayarlandı.

resim açıklamasını buraya girin

Bu ikinci ekran görüntüsü, "Üst Çubukların Altında" onay kutusunun işaretini kaldırdığınızda ne olacağını gösterir. Gördüğünüz gibi, görünüm denetleyicilerinin görünümü, y başlangıç ​​noktasının gezinme çubuğunun hemen altında olması için uygun şekilde kaydırılmıştır.

resim açıklamasını buraya girin

Bu aynı zamanda program aracılığıyla program aracılığıyla da gerçekleştirilebilir -[UIViewController edgesForExtendedLayout]. İşte için sınıf referansı için bir bağlantı edgeForExtendedLayout ve için UIRectEdge

[self setEdgesForExtendedLayout:UIRectEdgeNone];

15
Aynı şeyi bir .xib dosyasında görüntülemek için nasıl yapabilirim?
bobics

2
Görünüme bir etiket ekledim ve talimatlarınızı
uyguladım

5
@bobics XIB sorununun cevabı "Yapamazsınız." Zaten IB aracılığıyla değil. Bir radar dosyası hazırlayın ve Apple'ın sonunda buna hitap etmesini umun.
memmons

Teşekkürler @ 0x7fffffff, Bu sadece aradığım ve çok yardımcı oldu bilgi oldu.
campo

33

Görüşümü programlı olarak oluşturdum ve bu benim için çalıştı:

- (void) viewDidLayoutSubviews {
    // only works for iOS 7+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;

        // snaps the view under the status bar (iOS 6 style)
        viewBounds.origin.y = topBarOffset * -1;

        // shrink the bounds of your view to compensate for the offset
        viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
        self.view.bounds = viewBounds;
    }
}

Kaynak (sayfa 39'un altındaki topLayoutGuide bölümünde).


Sonunda bunun için gerçekten işe yarayan bir cevap buldum. İyi iş!
StuartM

1
Gezinme çubuğu gizlendiğinde görünüm denetleyicisinin görünümünün durum çubuğunun altında görünmesi sorununu çözmek için, durum çubuğunun altına görünümü ekleyen kod budur.
MiKL

Not: Bu, görünümünüzün alt kısmını ekrandan itecektir.
memmons

1
Ayrıca, yalnızca iOS7 için oluşturmadığınız sürece , yukarıdaki kod bir hata verir - topLayoutGuideyalnızca iOS7'dir.
memmons

1
Ayrıca ana görünümünüz bir UITableView olduğunda viewDidLayoutSubviews her kaydırmada çağrılacaktır. UITableView ürününüz, yüksekliği 15 piksel olana kadar ölçeklendirilir. Bu kodu yalnızca bir kez çalıştırmak için bir bayrak ekleyin. ;)
Thomas Johannesmeyer

30

İOS 10+ sürümünde NIB'ler / XIB dosyalarıyla da çalışan Swift 3 / Swift 4 çözümü:

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}

Bu bana yardımcı olan şey ... Çok Basit. Teşekkürler :-)
Hernan Arber

Teşekkür ederim gerçekten yararlı
Muhammad Ahmed Baig

10.x Swift 3+ IMO için en iyi çözüm
budur

10

Görünümün yarı saydam gezinme çubuğuna sahip olmasını istiyorsanız (ki bu hoş bir şeydir) bir contentInset veya benzeri ayarlamanız gerekir.

İşte nasıl yaparım:

// Check if we are running on ios7
if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7) {
      CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame];
      float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height;

      myContentView.contentInset = UIEdgeInsetsMake(heightPadding, 0.0, 0.0, 0.0);
}

3
neden doğrudan 7.0
Leena

1
lol anladım: küçük eklenen belirli bir sürüme karşı kontrol daha az sağlamdır. Ancak, değerin BÜYÜK veya eşit olup olmadığını kontrol edersiniz, bu nedenle 7.0 ile karşılaştırmak burada iyi olur;)
EeKay 18:13

1
@ leena - Bu 7.x ve sonraki özellikler - bu yüzden sürüm 7 veya daha büyük olup olmadığını kontrol edin ve çek küçük değişiklikleri atlayın.
Magnus

2
Ben Tabbar arkasında görüntülenen tableView beeing ile ilgili bir sorun vardı. Bu benim tablonun son satırı asla Tabbar üzerinde kaydırmak yaptı. Bunu şöyle düzelttim: myTableView.contentInset = UIEdgeInsetsMake (0, 0.0, TabbarHeight, 0)
James Laurenstin 22:13

contentInsetbir malıdır UIScrollView. Ya benim ana görüşüm bir alt sınıf değilse UIScrollView. O zaman çakışma problemini nasıl düzeltebilirim?
Pwner

9

edgesForExtendedLayoutBununla birlikte, uygulamayı iOS 7 SDK üzerinden oluşturup iOS 6'ya dağıtırsanız, gezinme çubuğu yarı saydam görünür ve altındaki görünümler gider. Bu nedenle, hem iOS 7 hem de iOS 6 için düzeltmek için bunu yapın:

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific

9

Uygulama plist dosyanızda bir satır ekleyin, "Denetleyici tabanlı durum çubuğu görünümünü görüntüle" olarak adlandırın ve NO olarak ayarlayın .


7

En basit hile NIB dosyasını açmak ve bu iki basit adımı yapmaktır:

  1. Sadece değiştirin ve tercih ettiğiniz şekilde ayarlayın:

Resim açıklamasını buraya girin

  1. Taşınmasını istediğiniz UIView / UIIMageView / ... öğelerini seçin. Benim durumumda sadece logo üst üste bindi ve deltayı +15 olarak ayarladım; (VEYA 1. adımda iOS 7'yi seçtiyseniz -15)

Resim açıklamasını buraya girin

Ve sonuç :

Önce Sonra


6
Çalışıyor, ancak bu bakımı zor bir çözüm gibi görünüyor. Sorunu düzeltmek yerine düzeltmek en iyisi olacaktır.
NLemay

tüm görünümün alt görünümleri için programlı olarak yapmak en iyisidir çünkü ana görünüme uygulanırsa çalışmaz
wildmonkey

5

Hızlı Çözüm:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.edgesForExtendedLayout = UIRectEdge.None
}

4
Bu artık edgeForExtendedLayout = []
Leon

1
Bu halka açık bir yanıt olduğu için aramayı unutmamalıyız:super.viewWillAppear(animated)
prodos

4

Stunner'ın cevabını genişletmek ve if iOS-7 olup olmadığını kontrol etmek açıklama istiyorum, çünkü iOS 6'da test ettiğimde uygulamam çökecek.

Ekleme şunları ekler:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

Bu yöntemi MyViewControler.mdosyanıza eklemenizi öneririm :

- (void) viewDidLayoutSubviews {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
    }
}

4

Hızlı 3

override func viewWillAppear(_ animated: Bool) {
    self.edgesForExtendedLayout = []
}

3

Reklamlarımı görüntülemek için Apple tarafından yazılmış BannerViewController ve BannerViewController gömülü bir ScrollViewController kullandığım bir senaryo var.

Gezinme çubuğunun içeriğimi gizlemesini önlemek için iki değişiklik yapmam gerekiyordu.

1) BannerViewController.m dosyasını değiştirin

- (void)viewDidLoad
{
   [super viewDidLoad];
   float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
   if (systemVersion >= 7.0) {
      self.edgesForExtendedLayout = UIRectEdgeNone;
   }
}

2) ScrollViewContoller'ımı değiştir

- (void)viewDidLoad
{
    [super viewDidLoad];
    float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (systemVersion >= 7.0) {
        self.edgesForExtendedLayout = UIRectEdgeBottom;
    }
}

Artık reklamlar Gezinme çubuğunun kapsamı yerine görünümün altında doğru bir şekilde gösteriliyor ve üstteki içerik kesilmiyor.


2

sadece görünümde aşağıdaki kodu ayarlayın görünecektir.

  if ([[[UIDevice currentDevice] systemVersion] floatValue]<= 7) {
self.edgesForExtendedLayout = UIRectEdgeNone;
 }

Benim durumumda işe yarayan tek şey bu.
goobliata


2

Swift 4.2 - Xcode 10.0 - iOS 12.0:

if #available(iOS 11.0, *) {} else {
  self.edgesForExtendedLayout = []
  self.navigationController?.view.backgroundColor = .white
}

1

Bana göre, en basit çözüm pliste iki anahtar eklemektir

resim açıklamasını buraya girin


+1, "Durum çubuğu başlangıçta gizli" = EVET, ancak "Denetleyici tabanlı durum çubuğu görünümünü görüntüle" = HAYIR eklenirken Durum çubuğundan kurtuldum.
Jonas Byström

1

Açılır listeden "Denetleyici tabanlı durum çubuğu görünümünü görüntüle" anahtarını bir satır olarak ekleyin info.plist. Bunun gibi bir şey:

Resim açıklamasını buraya girin


interesting.it cocos2d projelerime yardımcı oldu. bu seçeneği değiştirdiğimde üst durum çubuğunun tamamen gittiğini veya göründüğünü görebiliyorum.
Kursat Turkay

1

İPad'imde (armv7, armv7s, amr64) uygulamamla aynı sorunu yaşadım ve başka bir UIViewController sunarak ve bunları çıkardıktan sonra durum çubuğunun altında gezinme çubuğuna gider ... Bunun için herhangi bir çözüm bulmak için çok zaman harcıyorum. Ben storyboard ve UIViewController için InterfaceBuilder içinde korkunç yapan i FullScreen -> Geçerli Bağlam Sunum ayarlamak ve bu sorunu gidermek. Uygulamamda yalnızca iPad = = iOS8.0 (iOS8.1 ile test) ve iOS 7.1 yüklü iPad'ler için çalışmıyor !!ekran görüntüsüne bakın


Benim durumumda, ana görüşüm tabBar ile örtüşüyordu ve neden hiçbir fikrim yoktu. Kenarları Uzat> Alt Çubukların Altında işaretlendi. Uygulamamın arka planı beyaz olduğu ve tabBar'ım üzerinde sadece bir miktar opaklık oluşturduğu için bunu fark etmek gerçekten zor oldu. Teşekkürler!
Jesus Rodriguez

0

Adımlar iOS 7'de durum çubuğunu gizleme:

1. uygulama info.plist dosyanıza gidin.

2.Ve Set, Görünüm denetleyicisi tabanlı durum çubuğu görünümü: Boolean NO

Umarım durum çubuğu sorununu çözdüm .....


0

Benim durumumda loadView () kesintiye uğramış
bu kod : self.edgesForExtendedLayout = UIRectEdgeNone

ancak loadView () 'i sildikten sonra her şey yolunda gitti

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.