父子控制器中的自訂導覽列,父子自訂導覽列

來源:互聯網
上載者:User

父子控制器中的自訂導覽列,父子自訂導覽列

提到自訂導覽列,大家首先想到的就是自己寫個自訂導航控制器,然後設定自己的導航控制器的主題。再把封裝著自己控制器的導航控制器的class填上自己寫的自訂nav如果遇到個別控制器的導覽列想與眾不同,就再寫個自訂nav然後再弄個新的導航控制器包裹自己。

 

可是,如果一個項目中用到了 父子控制器,上面的這種做法就會沒有效果。原因就是取不到導覽列。

比如我做的大概架構是一個collectionView的循環參考,讓一個個tableview都是封裝在我的collectionViewcell裡面的,然后里面的的tableview的cell點擊之後會push一個新的介面。這時候不管你把這個push的新介面怎麼設定導覽列樣式 在程式中都是看不見的,因為只能看到最上層,就是collectionViewController的導覽列。

(這裡暫時就沒了,因為好多種結果,截太麻煩了,相信大家能理解文字的意思)

而且就算設定導覽列的主題大家也都知道,這段代碼也都是寫在首次調用本類時方法裡

+ (void)initialize{    // 設定導覽列的主題    UINavigationBar *navBar = [UINavigationBar appearance];    [navBar setBarTintColor:[UIColor redColor]];}

之後再想在動態修改,導覽列的背景色或是背景圖片都是改不了了,只有在一載入時就寫好。我曾試過在push出新的控制器和pop彈棧之後發出通知在這裡更改樣式,但是都是無效的,改不了。

 

 

 

 

 

,這個裡面控制器是兩個scrollView,一個是標題列scrollView,一個是下面的內容也是一個scrollView。 (之所以用scrollview是為了每個頁面懶載入,效能更好),然後在scrollView中嵌套了一個個tableViewController。 是把tableViewController的view加到 scrollView的subViews裡。

scrollView是主控制器view的subView 那這個tableViewController的view就是主控制器的 subView的subView。

這裡要說一下關於父子控制器的注意點就是:如果把A的view加到了B的view的subViews裡 那這個A的控制器也必須加到這個B的控制器的childControllers裡。

不然view過去了控制器卻沒有 他不就是沒人管了?

上面這個效果 主要用到了一個方法就是導覽列的隱藏方法

當然在設定介面的時候,上面的箭頭和跟帖都是要自己自訂的一個普通的view不是導覽列,可以把他當作導覽列來使用。(董鉑然部落格園原創)點擊返回會把棧頂控制器彈棧,點擊跟帖會再push一個評論控制器。

然後再這個詳情控制器將要顯示時把導覽列隱藏,再在這個詳情頁將要彈棧時設定導覽列顯示就好。

- (void)viewWillAppear:(BOOL)animated{    [self.navigationController setNavigationBarHidden:YES animated:YES];}
- (IBAction)backBtnClick:(id)sender {    [self.navigationController popViewControllerAnimated:YES];    [self.navigationController setNavigationBarHidden:NO animated:YES];}

 

這裡還有個注意點就是 要把導覽列隱藏寫在合適的方法裡,如果寫在將要跳轉的方法prepareForSegue裡就會有抽搐的bug

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{    if ([segue.destinationViewController isKindOfClass:[SXDetailController class]]) {                NSInteger x = self.tableView.indexPathForSelectedRow.row;        SXDetailController *dc = segue.destinationViewController;        dc.newsModel = self.arrayList[x];        [self.navigationController setNavigationBarHidden:YES animated:YES];    }else{        NSInteger x = self.tableView.indexPathForSelectedRow.row;        SXPhotoSetController *pc = segue.destinationViewController;        pc.newsModel = self.arrayList[x];        [self.navigationController setNavigationBarHidden:YES animated:YES];    }    }

 

這個是反面教材,仔細看導覽列有個抽搐的bug

 

 

 

 

有的人可能會嘗試乾脆直接不用導航控制器了 自己設定按鈕控制push和pop

但是這樣系統是不允許的 會報錯,報錯的大概意思就是 你不能給一個沒有導航控制器的控制器添加push操作。

我上面用的方法是雖然把導航控制器隱藏了,但他的功能還在。

 

隱藏導覽列非常好用,可是會遇到一個問題,就是隱藏了導覽列之後,push出的介面無法向左滑動返回。

這個問題類似於: 在導覽列的左上方自訂了一個返回按鈕把原本的返回按鈕給覆蓋了。導致無法實現滑動返回

解決方案是這樣,再將控制器push的代碼之後 或者在prepareForSegue 方法裡面加上這行代碼

 if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {            self.navigationController.interactivePopGestureRecognizer.delegate = nil;        }

因為你覆蓋了系統的返回按鈕,(董鉑然部落格園原創)系統將會通過代理禁用這個滑動返回功能,你提前把代理給踢了,這樣滑動返回功能就能報住了。

為了安全起見 最好把主控制器的即將顯示加上這行代碼

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

如果不加這行代碼 可能你一push再拉回來導覽列還是隱藏著的。因為剛才我們只在返回按鈕觸發時設定了導覽列顯示對吧。

最終效果可以達到這樣

 

哪裡覺得不對勁或者哪裡覺得看不懂 歡迎與我交流 歡迎關注我

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.