يقوم iPhone بإخفاء شريط التنقل في الصفحة الأولى فقط

StackOverflow https://stackoverflow.com/questions/845583

سؤال

لدي الكود أدناه الذي يخفي ويظهر شريط التنقل.يتم إخفاؤه عند تحميل العرض الأول ثم يتم إخفاؤه عند استدعاء "الأطفال".المشكلة هي أنني لا أستطيع العثور على الحدث/الإجراء لتشغيله لإخفائه مرة أخرى عندما يعودون إلى عرض الجذر....

لدي زر "اختبار" في الصفحة الجذرية يقوم بالإجراء يدويًا ولكنه ليس جميلًا وأريد أن يكون تلقائيًا.

-(void)hideBar 
{
    self.navController.navigationBarHidden = YES;
}
-(void)showBar 
{       
    self.navController.navigationBarHidden = NO;
}
هل كانت مفيدة؟

المحلول

أفضل حل وجدته هو القيام بما يلي في تحكم العرض الأول.

ج موضوعية

- (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];
}

سويفت

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

سيؤدي هذا إلى تحريك شريط التنقل من اليسار (جنبًا إلى جنب مع العرض التالي) عند الضغط على العرض التالي UIViewController على المكدس، وقم بالتحريك بعيدًا إلى اليسار (مع العرض القديم)، عندما تضغط على زر الرجوع الموجود على UINavigationBar.

يرجى ملاحظة أيضًا أن هذه ليست طرقًا مفوضة، بل أنت متجاوز UIViewControllerتنفيذ هذه الأساليب، ووفقًا للوثائق التي قمت بها يجب أن تستدعي تطبيق super في مكان ما في التنفيذ الخاص بك.

نصائح أخرى

وثمة نهج آخر وجدت لتعيين مندوب للNavigationController:

navigationController.delegate = self;

وواستخدام setNavigationBarHidden في navigationController: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];
}

وطريقة سهلة لتخصيص سلوك لكل ViewController في مكان واحد.

واحد قرص طفيف كان لزاما على إجابات أخرى هو إظهار شريط في viewWillDisappear إلا إذا كان السبب هو اختفاء يرجع إلى عنصر الملاحة يتم دفعها على ذلك. وذلك لأن وجهة نظر يمكن أن تختفي لأسباب أخرى.

وهكذا أنا فقط إظهار شريط إذا كان هذا الرأي لم يعد العلوي رأي:

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

    [super viewWillDisappear:animated];
}

سأضع الكود في viewWillAppear مندوب في كل طريقة عرض يتم عرضها:

مثل هذا حيث تحتاج إلى إخفاءه:

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

مثل هذا حيث تحتاج إلى إظهاره:

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

وفي سويفت 3:

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

الإجابة المقبولة حاليًا لا تتطابق مع السلوك المقصود الموضح في السؤال.يطلب السؤال إخفاء شريط التنقل على وحدة تحكم العرض الجذر، ولكنه مرئي في كل مكان آخر، ولكن الإجابة المقبولة تخفي شريط التنقل على وحدة تحكم عرض معينة.ماذا يحدث عندما يتم دفع مثيل آخر لوحدة تحكم العرض الأول إلى المكدس؟سيؤدي ذلك إلى إخفاء شريط التنقل على الرغم من أننا لا ننظر إلى وحدة التحكم في عرض الجذر.

بدلاً من ذلك، @Chad M.'s إستراتيجية من استخدام UINavigationControllerDelegate هو فكرة جيدة، وهنا حل أكثر اكتمالا.خطوات:

  1. فئة فرعية UINavigationController
  2. تنفيذ -navigationController:willShowViewController:animated طريقة لإظهار شريط التنقل أو إخفائه بناءً على ما إذا كان يعرض وحدة التحكم في عرض الجذر
  3. تجاوز طرق التهيئة لتعيين الفئة الفرعية UINavigationController كمفوض خاص بها

يمكن العثور على الكود الكامل لهذا الحل في هذا جوهر.هنا navigationController:willShowViewController:animated تطبيق:

- (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];
    }
}

وبعد تجارب متعددة هنا هو كيف حصلت عليه العمل من أجل ما أردت. هذا ما كنت أحاول. - لدي وجهة نظر مع صورة. وأردت أن يكون صورة يذهب كامل الشاشة. - لدي وحدة تحكم الملاحة مع tabBar جدا. لذلك أنا بحاجة لإخفاء ذلك أيضا. - كما كان متطلباتي الرئيسي ليس فقط الاختباء، ولكن وجود يتلاشى أثر جدا في حين إظهار وإخفاء

.

وهذه هي الطريقة التي حصلت عليه العمل.

الخطوة 1 - لدي صورة والصنابير المستخدم على تلك الصورة مرة واحدة. I التقاط هذه البادرة ودفعها إلى imageViewController جديدة، لها في imageViewController، أريد أن يكون صورة كاملة شاشة.

- (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];
} 

والخطوة 2 - كل هذه الخطوات أدناه في ImageViewController

والخطوة 2.1 - في ViewDidLoad، وتظهر نافبار

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

والخطوة 2.2 - في viewDidAppear، وإعداد مهمة الموقت مع تأخير (لقد وضعتها ل1 ثانية التأخير). وبعد هذا التأخير، إضافة يتلاشى تأثير. أنا أستخدم ألفا لاستخدام يتلاشى.

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

وخطوة 2.3 - تحت viewWillAppear، إضافة لفتة singleTap إلى الصورة وجعل شفافة شريط التنقل.

- (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];
 }

والخطوة 3 - وأخيرا في viewWillDisappear، للتأكد من وضع كل الاشياء الظهر

- (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];
}

أعط رصيدي لإجابة @chad-m.

هنا هو الإصدار سويفت:

  1. إنشاء ملف جديد 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. قم بتعيين فئة UINavigationController الخاصة بك في StoryBoard إلى MyNavigationControllerMyNavigationController هذا كل شيء!

الفرق بين إجابة chad-m وإجابة لي:

  1. وراثة من UINavigationController، لذلك لن تلوث rootViewController الخاص بك.

  2. يستخدم self.viewControllers.first بدلا من homeViewController, ، لذلك لن تفعل ذلك 100 مرة مقابل 100 وحدة تحكم UINavigationControllers في لوحة قصة واحدة.

في حال كان أي شخص لا يزال يواجه مشكلة مع تم إلغاء الخطأ في التمرير السريع للخلف كما علقfabb في الإجابة المقبولة.

تمكنت من إصلاح هذا عن طريق التجاوز viewDidLayoutSubviews, ، بالإضافة إلى viewWillAppear/viewWillDisappear كما هو مبين أدناه:

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

في حالتي، لاحظت أن السبب هو وحدة تحكم العرض الجذر (حيث يتم إخفاء التنقل) ووحدة تحكم العرض المدفوعة (يتم عرض التنقل) لديه أنماط مختلفة لشريط الحالة (على سبيل المثالظلام ونور).في اللحظة التي تبدأ فيها السحب للخلف لإخراج وحدة التحكم في العرض، سيكون هناك رسم متحرك ملون إضافي لشريط الحالة.إذا حررت إصبعك لإلغاء البوب ​​التفاعلي، بينما لم يتم الانتهاء من الرسوم المتحركة لشريط الحالة, ، اختفى شريط التنقل إلى الأبد!

ومع ذلك، لا يحدث هذا الخطأ إذا كانت أنماط شريط الحالة لكلا جهازي التحكم في العرض متماثلة.

إذا ما كنت أريده هو لإخفاء شريط التنقل تماما في وحدة تحكم، وإيجاد حل أنظف بكثير هو، في وحدة تحكم الجذر، يكون شيئا مثل:

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

عند دفع وجهة نظر الطفل في وحدة تحكم، وشريط الإنتقال تبقى مخفية. إذا كنت ترغب في عرضه فقط في الطفل، عليك بإضافة التعليمة البرمجية لعرض it(self.navigationController.navigationBarHidden=NO;) في رد viewWillAppear، وبالمثل رمز لإخفائه على viewWillDisappear

وربما تكون أبسط التنفيذ أن يكون مجرد رأي كل وحدة تحكم تحديد ما إذا كان يتم إخفاء شريط التنقل، أو ليس في طريقة viewWillAppear:animated: لها. نفس النهج يعمل بشكل جيد لإخفاء / إظهار شريط الأدوات أيضا:

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

وشريط التنقل إخفاء فقط على الصفحة الأولى لا يمكن أن يتحقق من خلال القصة المصورة أيضا. على القصة المصورة، غوتو <م> التنقل المراقب Scene-> شريط التنقل . وحدد '<م> مختفي ' الملكية من مفتش <م> سمات . هذا سوف إخفاء شريط التنقل بدءا من viewcontroller الأول حتى جعل لها مرئية للviewcontroller المطلوبة.

يمكن تعيين

وشريط التنقل إلى مرئية في رد ViewWillAppear ViewController ل.

-(void)viewWillAppear:(BOOL)animated {

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

سويفت 4:

في وحدة تحكم العرض التي تريد إخفاء شريط التنقل منها.

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

وخلال تنفيذ هذه التعليمات البرمجية في ViewController الخاص بك يمكنك الحصول على هذا التأثير  في الواقع هو، إخفاء شريط التصفح عند شن أن المراقب المالي خدعة

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

ووإظهار شريط التنقل عندما المستخدم ترك تلك الصفحة قيام بذلك هو viewWillDisappear

- (void)viewWillDisappear:(BOOL)animated {
    [self.navigationController setNavigationBarHidden:NO animated:YES];
    [super viewWillDisappear:animated];
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top