iPhone Gezinti Çubuğunu yalnızca ilk sayfada gizle


381

Aşağıda gezinme çubuğunu gizleyen ve gösteren kodu var. İlk görünüm yüklendiğinde gizlenir ve ardından "children" çağrıldığında gizlenir. Sorun kök olayına geri döndüklerinde tekrar gizlemek için tetiklemek için olay / eylem bulamıyorum ....

Kök sayfasında manuel olarak eylemi yapan bir "test" düğmesi var ama hoş değil ve otomatik olmasını istiyorum.

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}

Yanıtlar:


1035

Bulduğum en güzel çözüm, ilk görünüm denetleyicisinde aşağıdakileri yapmaktır .

Objective-C

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [super viewWillAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:animated];
    [super viewWillDisappear:animated];
}

hızlı

override func viewWillAppear(animated: Bool) {
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
    super.viewWillAppear(animated)
}

override func viewWillDisappear(animated: Bool) {
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
    super.viewWillDisappear(animated)
} 

Bu UIViewController, yığındaki bir sonraki öğeye bastığınızda gezinme çubuğunun soldan (bir sonraki görünümle birlikte) animasyon yapmasına ve üzerindeki eski düğmeye bastığınızda sola (eski görünümle birlikte) UINavigationBar.

Ayrıca, bunların temsilci yöntemler olmadığını UIViewController, bu yöntemlerin uygulanmasını geçersiz kıldığınızı ve belgelere göre, uygulamanızın bir yerinde süper uygulamanın uygulamasını çağırmanız gerektiğini lütfen unutmayın .


2
Bu tamamen sallanıyor! En az bir gündür bununla mücadele ediyordum. Teşekkürler!!!
James Testa

26
UYARI: Hızlı bir geri kaydırma işlemi yaparken çok kötü bir hata oluşur. A'nın (gezinme çubuğu yok) ve B'nin (gezinme çubuğu ile) yığının üzerine itildiğini varsayın. B görünümünde ve hızlı bir geri silme yaparken, ancak B'de kalacak kadar erken bırakın, navbar hala gizlenir. Artık geri dönmenin bir yolu yok. Bunun nedeni animated=YES. Çirkin göründüğünü biliyorum animated=NO, ancak navbar'ı gizlemek için animasyon henüz bitmediğinde, tekrar göstermek için animasyon yok sayılıyor. Henüz çözüm yok.
fabb

3
Swift'te func viewWillAppear (animated: Bool) geçersiz kılma {self.navigationController? .SetNavigationBarHidden (true, animated: true) super.viewWillAppear (true)} func viewWillDisappear (animated: Bool) {self.navigationController? .SetNavigationBarHidden (false, false, animated: false) super.viewWillDisappear (true)}
Kitson

7
Soru 2010'da cevaplandı ve 2015'in sonunda bana yardımcı oldu! Teşekkür ederim.
oyalhi

1
İşte buna efsanevi cevap diyorum. Mükemmel hile arkadaşı. Onlarca yıldan sonra bile çalışıyor ... Aynısını hızlıca, kusursuz bir şekilde uyguladı. Cevabınız için +1 @Alan Rogers
onCompletion

62

Bulduğum başka bir yaklaşım, aşağıdakiler için bir temsilci ayarlamaktır NavigationController:

navigationController.delegate = self;

ve kullanımı setNavigationBarHiddeniçindenavigationController:willShowViewController:animated:

- (void)navigationController:(UINavigationController *)navigationController 
      willShowViewController:(UIViewController *)viewController 
                    animated:(BOOL)animated 
{   
    // Hide the nav bar if going home.
    BOOL hide = viewController != homeViewController;
    [navigationController setNavigationBarHidden:hide animated:animated];
}

Her biri için davranışı ViewControllertek bir yerde özelleştirmenin kolay yolu .


Bu ne zaman aranacak?
Zalak Patel

1
Mükemmel çözüm. Bu kabul edilen cevap olmalı. Teşekkürler!
Samah

Mükemmel cevap. İlk görünüm denetleyicisindeki viewWillAppear ve viewWillDisappear yöntemlerini geçersiz kılamamamız durumunda da çalışır.
pjuzeliunas

1
Muhteşem. Seçilen cevap iyi çalışıyor, ancak sadece basit uygulamalarda. Bu yanıt gezinme çubuğu bir sekme denetleyicisindeyken çalışır ve çeşitli VC'leri çeşitli şekillerde iter / sunar.
Jonathan Winger-Lang

Bu en iyi cevap. En iyi cevap @ fabb 'ın açıklaması gibi bir hata oluşabilir .
Ryan.Yuen

18

Diğer cevaplarda yapmak zorunda olduğum hafif bir değişiklik sadece görünümde çubuğu göstermektir. Bunun nedeni, görünümün başka nedenlerle ortadan kalkabilmesidir.

Bu yüzden çubuğu bu görünüm artık en üstteki görünüm değilse göstereceğim:

- (void) viewWillDisappear:(BOOL)animated
{
    if (self.navigationController.topViewController != self)
    {
        [self.navigationController setNavigationBarHidden:NO animated:animated];
    }

    [super viewWillDisappear:animated];
}

3
+1, genellikle kalıcı bir iletişim kutusuna basarken gezinme çubuğunu göstermek istemezsiniz.
João Portela

17

Kodu gösterilen her görünümde viewWillAppear temsilcisine koyardım :

Gizlemeniz gereken bu gibi:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject hideBar];
}

Göstermeniz gereken yer bu şekilde:

- (void)viewWillAppear:(BOOL)animated
{
        [yourObject showBar];
}

Lee, bu senin sorununu çözerse, Pablo'yu "çözüm" cevabı olarak işaretle.
Rog

2
Bununla ilgili tek sorun, bir görünümden diğerine geçerken gezinme çubuğunun "dışarı çıkıp" görünmesi. Gezinme çubuğunun ilk görünümde orada olmaması mümkün mü ve ikinci görünüm yerine oturduğunda, herhangi bir patlama olmadan gezinme çubuğuna sahip mi?
Henning

2
@henning NavBar slaytını beklediğiniz gibi içeri / dışarı yapmak için setNavigationBarHidden: animated: öğesini kullanmanız gerekir. Aşağıdaki Alan Rogers'ın cevabına bakınız (gerçekten "çözüm" olarak işaretlenmesi gerekir).
Nick Forge

2
Bu cevap biraz yanlış (viewWill / DidAppear) süper çağırıyor olmalıdır. Ayrıca HER görünüm denetleyicisine eklemeniz gerekmeyen bir çözüm için aşağıdaki cevabımı inceleyin.
Alan Rogers

15

Şu anda kabul edilen cevap, soruda açıklanan amaçlanan davranışla eşleşmiyor. Soru, gezinme çubuğunun kök görünüm denetleyicisine gizlenmesini ister, ancak her yerde görünür olmasını ister, ancak kabul edilen yanıt, belirli bir görünüm denetleyicisindeki gezinme çubuğunu gizler. İlk görünüm denetleyicisinin başka bir örneği yığına itildiğinde ne olur? Kök görünüm denetleyicisine bakmamıza rağmen gezinme çubuğunu gizleyecektir.

Bunun yerine, @Chad M.'nin bu stratejiyi kullanma stratejisiUINavigationControllerDelegate iyi ve burada daha eksiksiz bir çözüm var. Adımlar:

  1. Alt sınıf UINavigationController
  2. -navigationController:willShowViewController:animatedGezinme çubuğunu kök görünüm denetleyicisini gösterip göstermediğine bağlı olarak gösterme veya gizleme yöntemini uygulama
  3. UINavigationController alt sınıfını kendi temsilcisi olarak ayarlamak için başlatma yöntemlerini geçersiz kılın

Bu çözümün tam kodunu bu Gist'te bulabilirsiniz . İşte navigationController:willShowViewController:animateduygulama:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    /* Hide navigation bar if root controller */
    if ([viewController isEqual:[self.viewControllers firstObject]]) {
        [self setNavigationBarHidden:YES animated:animated];
    } else {
        [self setNavigationBarHidden:NO animated:animated];
    }
}

2
Bu, kabul edilenden daha uygun bir cevaptır
Pavel Gurov

14

Swift 3'te:

override func viewWillAppear(_ animated: Bool) {
    navigationController?.navigationBar.isHidden = true
    super.viewWillAppear(animated)
}


override func viewWillDisappear(_ animated: Bool) {
    if (navigationController?.topViewController != self) {
        navigationController?.navigationBar.isHidden = false
    }
    super.viewWillDisappear(animated)
}

! = self'i neden kontrol ettiğinizi açıklar mısınız?
Kitson

2
@Kitson, user486646 'cevabını kontrol edin: Diğer cevaplarda yapmak zorunda olduğum hafif bir değişiklik, yalnızca görünümde çubuğu göstermektir. Bunun nedeni, görünümün başka nedenlerle ortadan kalkabilmesidir. Bu yüzden artık bu görünüm artık en üstte
görünmüyorsa çubuğu göstereceğim

navcontroller.navagationBarHiddenKullanırsanız, tüm navigasyon denetleyicisini kıracak gibi görünüyor (ileri geri kaydırma yok). Çalışmak için bunun navigationController?.navigationBar.hiddenyerine kullandım . Kaydırma işlemi hala işe yarıyor ve boş alan bırakmıyor çünkü bir yığın görünümü ya da başka bir şey içerisindeymiş gibi görünüyor
Sirens

8

@ Chad-m'nin cevabına kredimi ver.

İşte Swift sürümü:

  1. Yeni bir dosya oluştur MyNavigationController.swift

import UIKit

class MyNavigationController: UINavigationController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.delegate = self
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController == self.viewControllers.first {
            self.setNavigationBarHidden(true, animated: animated)
        } else {
            self.setNavigationBarHidden(false, animated: animated)
        }
    }

}
  1. StoryBoard'daki UINavigationController sınıfınızı MyNavigationController olarak ayarlayın İşte bu kadar!MyNavigationController

Chad-m'nin cevabı ve benimki arasındaki fark:

  1. UINavigationController öğesinden devralın, böylece rootViewController'ınızı kirletmezsiniz.

  2. kullanmak self.viewControllers.firstyerine homeViewController, 1 StoryBoard'da 100 UINavigationController'ınız için bunu 100 kez yapmayacaksınız.


Bunun en temiz cevap olduğunu düşünün. Teşekkürler
DaSilva

6

Burada birkaç denemeden sonra istediğim şey için nasıl çalıştıracağım. Ben de bunu deniyordum. - Resimli bir görüşüm var. ve görüntünün tam ekran görüntülenmesini istedim. - TabBar'lı bir navigasyon denetleyicim de var. Yani bunu da saklamam gerekiyor. - Ayrıca, temel gereksinim sadece saklanmak değil, aynı zamanda gösterme ve gizleme sırasında da solma etkisine sahip olmaktı.

Bu şekilde çalıştırdım.

Adım 1 - Bir resmim var ve kullanıcı bu resme bir kez dokunuyor. Ben bu hareketi yakalamak ve yeni içine itmek imageViewController, onun içinde, imageViewControllertam ekran görüntü istiyorum.

- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {  
NSLog(@"Single tap");
ImageViewController *imageViewController =
[[ImageViewController alloc] initWithNibName:@"ImageViewController" bundle:nil];

godImageViewController.imgName  = // pass the image.
godImageViewController.hidesBottomBarWhenPushed=YES;// This is important to note. 

[self.navigationController pushViewController:godImageViewController animated:YES];
// If I remove the line below, then I get this error. [CALayer retain]: message sent to deallocated instance . 
// [godImageViewController release];
} 

Adım 2 - Aşağıdaki tüm bu adımlar ImageViewController'da

Adım 2.1 - ViewDidLoad'da navBar'ı gösterin

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(@"viewDidLoad");
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}

Adım 2.2 - In viewDidAppear, gecikmeli bir zamanlayıcı görevi ayarlayın (1 sn gecikme için ayarladım). Ve gecikmeden sonra solma efekti ekleyin. Solmayı kullanmak için alfa kullanıyorum.

- (void)viewDidAppear:(BOOL)animated
{
NSLog(@"viewDidAppear");

myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self     selector:@selector(fadeScreen) userInfo:nil repeats:NO];
}

- (void)fadeScreen
{
[UIView beginAnimations:nil context:nil]; // begins animation block
[UIView setAnimationDuration:1.95];        // sets animation duration
self.navigationController.navigationBar.alpha = 0.0;       // Fades the alpha channel of   this view to "0.0" over the animationDuration of "0.75" seconds
[UIView commitAnimations];   // commits the animation block.  This Block is done.
}

adım 2.3 - altında viewWillAppear, resme singleTap hareketi ekleyin ve navBar'ı yarı saydam yapın.

- (void) viewWillAppear:(BOOL)animated
{

NSLog(@"viewWillAppear");


NSString *path = [[NSBundle mainBundle] pathForResource:self.imgName ofType:@"png"];

UIImage *theImage = [UIImage imageWithContentsOfFile:path];

self.imgView.image = theImage;

// add tap gestures 
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];  
[self.imgView addGestureRecognizer:singleTap];  
[singleTap release];  

// to make the image go full screen
self.navigationController.navigationBar.translucent=YES;
}

- (void)handleTap:(UIGestureRecognizer *)gestureRecognizer 
{ 
 NSLog(@"Handle Single tap");
 [self finishedFading];
  // fade again. You can choose to skip this can add a bool, if you want to fade again when user taps again. 
 myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self  selector:@selector(fadeScreen) userInfo:nil repeats:NO];
 }

Adım 3 - Son olarak viewWillDisappear, tüm şeyleri geri koyduğunuzdan emin olun

- (void)viewWillDisappear: (BOOL)animated 
{ 
self.hidesBottomBarWhenPushed = NO; 
self.navigationController.navigationBar.translucent=NO;

if (self.navigationController.topViewController != self)
{
    [self.navigationController setNavigationBarHidden:NO animated:animated];
}

[super viewWillDisappear:animated];
}

4

Herkesin hızlı geri silme işlemi ile ilgili sorun yaşamaya devam etmesi durumunda , @fabb kabul edilen yanıta yorum yaptığında hatayı iptal etti.

Ben geçersiz kılarak bu sorunu gidermek için yönetmek viewDidLayoutSubviewsek olarak, viewWillAppear/viewWillDisappearaşağıda gösterildiği gibi:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
}

//*** This is required to fix navigation bar forever disappear on fast backswipe bug.
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.navigationController?.setNavigationBarHidden(false, animated: false)
}

Benim durumumda, bunun nedeni, kök görünüm denetleyicisinin (gezinmenin gizlendiği yerde) ve itilen görünüm denetleyicisinin (gezinme gösterildi) farklı durum çubuğu stillerine (ör. Koyu ve açık) sahip olduğunu fark ettim . Görünüm denetleyicisini açmak için geri kaydırmayı başlattığınız anda, ek durum çubuğu renk animasyonu olacaktır. Durum çubuğu animasyonu bitmediğinde , etkileşimli pop'u iptal etmek için parmağınızı serbest bırakırsanız , gezinme çubuğu sonsuza kadar ortadan kalkmıştır!

Ancak, her iki görünüm denetleyicisinin durum çubuğu stilleri aynı ise, bu hata oluşmaz.


1

İstediğiniz şey gezinme çubuğunu denetleyicide tamamen gizlemekse, kök denetleyicide şöyle bir şey elde etmek çok daha temiz bir çözümdür:

@implementation MainViewController
- (void)viewDidLoad {
    self.navigationController.navigationBarHidden=YES;
    //...extra code on view load  
}

Denetleyicide bir alt görünüme bastığınızda, Gezinme Çubuğu gizli kalır; yalnızca alt öğede görüntülemek istiyorsanız it(self.navigationController.navigationBarHidden=NO;), viewWillAppeargeri aramada görüntülenecek kodu ve benzer şekilde gizlemek için kodu eklersinizviewWillDisappear


0

En basit uygulama, her bir görünüm denetleyicisinin gezinme çubuğunun viewWillAppear:animated:yönteminde gizli olup olmadığını belirtmesini sağlamak olabilir . Aynı yaklaşım araç çubuğunu gizlemek / göstermek için de işe yarar:

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setToolbarHidden:YES/NO animated:animated];
    [super viewWillAppear:animated];
}

Aslında, önerim yalnızca araç çubuğu için anlamlıdır, çünkü gezinme çubuğunu eşleşen bir çağrı olmadan gizlemek, kullanıcıların geçerli görünümden geri gidememesini sağlayacaktır.
SteveCaine

0

Gezinme çubuğunu yalnızca ilk sayfada gizlemek, film şeridi üzerinden de elde edilebilir. Film şeridinde Gezinti Denetleyicisi Sahne-> Gezinme Çubuğu'na gidin . Ve Nitelikler denetçisinden ' Gizli ' özelliğini seçin . Bu, ilk görüş kontrolöründen başlayarak gerekli görüş kontrolörü için görünür hale gelene kadar gezinme çubuğunu gizleyecektir.

Gezinme çubuğu, ViewController'ın ViewWillAppear geri aramasında görünür olarak yeniden ayarlanabilir.

-(void)viewWillAppear:(BOOL)animated {

    [self.navigationController setNavigationBarHidden:YES animated:animated];
    [super viewWillAppear:animated];                                                  
}

0

Hızlı 4:

Görünüm denetleyicisinde gezinme çubuğunu gizlemek istediğinizde.

override func viewWillAppear(_ animated: Bool) {
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
    super.viewWillAppear(animated)
}

override func viewWillDisappear(_ animated: Bool) {
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
    super.viewWillDisappear(animated)
}

-1

Bu kodu ViewController'ınıza uygulayarak bu efekti elde edebilirsiniz Aslında hile, bu Denetleyici başlatıldığında navigationBar'ı gizleyin

- (void)viewWillAppear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:YES animated:YES];
    [super viewWillAppear:animated];
}

ve kullanıcı bu sayfadan ayrıldığında gezinme çubuğunu göster, bunu görüntüle viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    [super viewWillDisappear:animated];
}
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.