亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

IOS導(dǎo)航欄的問題
天蓬老師
天蓬老師 2017-04-17 17:39:37
0
5
453

ios 兩個狀態(tài)欄 背景圖片不一樣 push過去正常顯示
返回(pop)回來,當(dāng)前的背景圖變成了push過去的那個導(dǎo)航欄的背景圖片.
用圖片演示:
1.這是控制器A:

2.設(shè)置push過去的控制器B:

3.點擊返回后的控制器A:

為什么控制器A的導(dǎo)航欄的背景圖片變成了控制器B的?如何修改?

代碼奉上:
自定義控制器的所有代碼:

#import "LMSNavigationController.h"

@interface LMSNavigationController ()

@end

@implementation LMSNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.navigationBar setTitleTextAttributes:
  @{NSFontAttributeName:[UIFont systemFontOfSize:16]}];
}


/**
 * 在這個方法中攔截所有push進(jìn)來的控制器
 */
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (self.childViewControllers.count > 0) {
        // 如果push進(jìn)來的不是第一個控制器
        UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [leftBtn setImage:[UIImage imageNamed:@"nav-back.png"] forState:UIControlStateNormal];
        [leftBtn setImage:[UIImage imageNamed:@"nav-back-hi.png"] forState:UIControlStateHighlighted];
        leftBtn.frame = CGRectMake(0, 0, 30, 30);
        [leftBtn addTarget:self action:@selector(popViewControllerAnimated:) forControlEvents:UIControlEventTouchUpInside];
        viewController.navigationItem.leftBarButtonItem  = [[UIBarButtonItem alloc]initWithCustomView:leftBtn];
        // 隱藏tabbar
        viewController.hidesBottomBarWhenPushed = YES;
    }
    
    //把導(dǎo)航欄底部的橫線去掉
    [self.navigationBar setShadowImage:[UIImage new]];
    
    // 這句super的push要放在后面, 讓viewController可以覆蓋上面設(shè)置的leftBarButtonItem
    // 意思是,我們?nèi)稳豢梢灾匦略趐ush控制器的viewDidLoad方法中設(shè)置導(dǎo)航欄的leftBarButtonItem,如果設(shè)置了就會覆蓋在push方法中設(shè)置的“返回”按鈕,因為 [super push....]會加載push的控制器執(zhí)行viewDidLoad方法。
    [super pushViewController:viewController animated:animated];
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

控制器A關(guān)鍵代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    //導(dǎo)航欄透明背景(nav-clearcolor-image是一張透明的圖片)
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"nav-clearcolor-image"] forBarMetrics:UIBarMetricsDefault];
    //把導(dǎo)航欄底部的橫線去掉
    [self.navigationController.navigationBar setShadowImage:[UIImage new]];
    //不顯示文字
    self.navigationItem.title = nil;
}

控制器B關(guān)鍵代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    UILabel *titleLabel = [[UILabel alloc]init];
    titleLabel.text = @"push過來的控制器";
    titleLabel.textColor = TitleTextColor;
    [titleLabel sizeToFit];
    self.navigationItem.titleView = titleLabel;
}
天蓬老師
天蓬老師

歡迎選擇我的課程,讓我們一起見證您的進(jìn)步~~

reply all(5)
伊謝爾倫

This is a question about the life cycle of UINavigationController (assuming your LMSNavigationController is its subclass) and UIViewController (hereinafter referred to as VC). . . UINavigationController(假設(shè)你們的 LMSNavigationController 是它的子類)以及 UIViewController (后文簡稱 VC )生命周期的問題。。。


簡單版本的答案

VC AviewDidLoad 改成 viewWillAppear 。
(下面還有個感覺上更優(yōu)的辦法。)

復(fù)雜版本(也雜不到哪去。。。)

先看看文檔對 viewDidLoad 是怎么描述的:

Called after the controller'??s view is loaded into memory.

在 VC 的視圖加載進(jìn)內(nèi)存的時候,這個方法會被調(diào)用。VC B pop 出去的時候不符合調(diào)用 VC AviewDidLoad 的條件,解釋如下:

UINavigationController 維護(hù)著一個 VC 棧,你 push、pop 那些 VC 時都是在操作這個棧。

push 的時候它會創(chuàng)建一個新的 VC 壓入棧中,就是你的 VC B,這個過程中這個新的 VC B 綁定的 view 經(jīng)歷了被加入內(nèi)存的過程, viewDidLoad 被調(diào)用。 VC B 處于棧頂,成為 topViewController 。 VC A 不再處于棧頂,但仍處于棧中,與它關(guān)聯(lián)的 view 仍在內(nèi)存中。再 pop VC B 出去的時候,VC A 關(guān)聯(lián)的 view 的 viewDidLoad 不再被調(diào)用。

所以 push pop 具體調(diào)用了什么?

上圖

Figure 1-5 Messages sent during stack changes

圖片來源:Navigation Controller 文檔的 Monitoring Changes to the Navigation Stack 部分

Monitoring Changes to the Navigation Stack
監(jiān)控導(dǎo)航棧的變化

push VC B 出去為例:

  1. VC B 作為當(dāng)前的 Topmost view controller ,其 viewWillDispear 最先被調(diào)用

  2. VC AviewWillAppear 被調(diào)用

  3. UINavigationControllerDelegatenavigationController:willShowViewController:animated: 被調(diào)用

  4. 轉(zhuǎn)場動畫(完成?不清楚)

  5. VC BviewDidDispear 被調(diào)用

  6. VC AviewDidAppear 被調(diào)用

  7. UINavigationControllerDelegatenavigationController:didShowViewController:animated:


    Simple version of the answer

    Change VC A’s viewDidLoad to viewWillAppear.
    (There is a better way below.) ??

    Complicated version (not too complicated...)

    ??Let’s first take a look at how the document describes viewDidLoad: ??
    ??Called after the controller's view is loaded into memory.??
    ??This method will be called when the VC view is loaded into memory. VC B pop does not meet the conditions for calling VC A's viewDidLoad when it goes out. The explanation is as follows: ?? ??UINavigationController maintains a VC stack. When you push and pop those VCs, you are operating this stack. ?? ??When push, it will create a new VC and push it onto the stack, which is your VC B. In this process, this new VC B > The bound view undergoes the process of being added to the memory, and viewDidLoad is called. VC B is on top of the stack and becomes topViewController. VC A is no longer on top of the stack, but still on the stack, and its associated view is still in memory. When pop VC B goes out, the viewDidLoad of the view associated with VC A will no longer be called. ??

    So what exactly does push pop call?

    ??Picture above?? ??Figure 1-5 Messages sent during stack changes

    Image source: Monitoring Changes to the Navigation Stack section of the Navigation Controller document??
    ??Monitoring Changes to the Navigation Stack
    Monitoring changes to the Navigation Stack??
    ??Take push VC B going out as an example: ??
    1. ??VC B As the current Topmost view controller, its viewWillDispear is called first??
    2. ??VC A's viewWillAppear is called??
    3. ??UINavigationControllerDelegate's navigationController:willShowViewController:animated: is called??
    4. ??Transition animation (completed? Unclear)??
    5. ??VC B's viewDidDispear is called??
    6. ??VC A's viewDidAppear is called??
    7. ??UINavigationControllerDelegate's navigationController:didShowViewController:animated: is called??

    In summary, VC A’s viewDidLoad can be changed to viewWillAppear. viewDidLoad 改成 viewWillAppear 即可。

    然而個人感覺更好的辦法是把兩個 viewDidLoad 都拆了,邏輯重寫在 UINavigationControllerDelegatenavigationController:willShowViewController:animated: 中。即可在一個位置解決改背景圖這個需求。

    完。


    更新,上面說的用 UINavigationControllerDelegate 的辦法:

        func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
            if self.childViewControllers.count > 1 {
                navigationController.navigationBar.setBackgroundImage(UIImage(named: "a"), forBarMetrics: .Default)
            } else {
                navigationController.navigationBar.setBackgroundImage(UIImage(named: "b"), forBarMetrics: .Default)
            }
        }
    

    viewWillAppear

    However, I personally feel that a better way is to dismantle both viewDidLoad and rewrite the logic in UINavigationControllerDelegate's navigationController:willShowViewController:animated: middle. You can solve the need to change the background image in one place.

    End.


    Update, use UINavigationControllerDelegate as mentioned above:

    rrreee

    ?? ??viewWillAppear I also tried it, it is exactly the same as this one, no black box appears. As far as this question is concerned, these two places meet your requirements. Just choose what you like. ?? ??The navigation controller that comes with the system has already done what it needs to do before the animation starts, so there will be no picture loading until halfway through the animation. The worst thing is that the animation will be stuck for a few seconds before it starts, and it won't start until it is loaded. ?? ??Your navigation controller is customized. Check the customized part to see if there are any black boxes caused by problems. ?? ?? (Also... I still don’t see where the background image has been changed. It’s not the button image that was changed on the first controller) ??
巴扎黑

All VCs under nav use the same navBar
You modified the navBar when entering B
but did not change it back when exiting B

小葫蘆

You have two navigation bar controllers (pop). The navigation bar returned is the same as the current navigation bar. You should create a proxy and reassign the value. (But it’s more troublesome)

阿神

You must have modified the color or image of the navigation bar in B

阿神

Try setting the background image of vc again in the viewWillAppear method of A

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template