ios - IOS8 SplitVC + TabBarController + NavigationController -


i'm doing universal app using size classes , i'm trying use splitview tabbarcontroller in master/primary view. before adding splitview worked fine, app crashes (the reason depends on hierarchy of views).

so tried same storyboard starting apple splitview template , add tabbarcontroller on master/primary view... same problem.

hierarchy - embedded master navigationcontroller in tabbarcontroller: splitvc (master) > tabbarcontroller > navigationcontroller > tableview splitvc (detail) > navigationcontroller > view

added code in appdelegate.m (as seen here stackoverflow questions ios8-tabbarcontroller... prevent detailview being presented modally):

- (bool)splitviewcontroller:(uisplitviewcontroller *)splitviewcontroller showdetailviewcontroller:(uiviewcontroller *)vc sender:(id)sender {         nslog(@"uisplitviewcontroller collapsed: %d", splitviewcontroller.collapsed);      if ([[uidevice currentdevice] userinterfaceidiom] == uiuserinterfaceidiomphone)     {         if (splitviewcontroller.collapsed) {             uitabbarcontroller *master = (uitabbarcontroller *) splitviewcontroller.viewcontrollers[0];             uinavigationcontroller *masternavigationcontroller = (uinavigationcontroller *)master.selectedviewcontroller;             uinavigationcontroller *destinationnavigationcontroller = (uinavigationcontroller *)vc;              // push detail view on navigation controller             [masternavigationcontroller pushviewcontroller:[destinationnavigationcontroller.viewcontrollers lastobject] animated:yes];              return yes;         }     }      return no; } 

it works fine... unless simulate in iphone6 plus, in case, after starting in portrait , selecting row, if rotate in landscape see detail view primary , secondary view.

without adding code in portrait orientation iphones detail view presented modally , of course without navigation buttons.

edit

after different tries , external helps i've made steps forward solution.

short version (see long version know why have this)

a correct solution problem subclass tabbarcontroller , make support methods:

@implementation mytabbarcontroller  - (void)showviewcontroller:(uiviewcontroller *)vc sender:(id)sender {     if ([self.selectedviewcontroller iskindofclass:uinavigationcontroller.class])         [self.selectedviewcontroller showviewcontroller:vc sender:sender];     else         [super showviewcontroller:vc sender:sender]; }  - (uiviewcontroller*)separatesecondaryviewcontrollerforsplitviewcontroller:(uisplitviewcontroller *)splitviewcontroller {     return [self.selectedviewcontroller separatesecondaryviewcontrollerforsplitviewcontroller:splitviewcontroller]; }  - (void)collapsesecondaryviewcontroller:(uiviewcontroller *)secondaryviewcontroller forsplitviewcontroller:(uisplitviewcontroller *)splitviewcontroller {     [self.selectedviewcontroller collapsesecondaryviewcontroller:secondaryviewcontroller forsplitviewcontroller:splitviewcontroller]; } 

now have problem viewcontrollers stack: iphone6plus (the 1 supporting both horizontal regular , compact) app crash if, when in landscape, change tab without selecting row (so detailview remain 1 previous tab) , rotate in portrait.

i know have implement separation , collapse methods managing views stacks can't figure how. can on this?

long version (splitviewcontroller behaviour)

normally split view controller , navigation controller work ensure call -showdetailviewcontroller:sender: view controller contained within split view controller results in new detail view controller being pushed onto navigation stack (when in horizontally compact environment). this, uisplitviewcontroller overrides -showdetailviewcontroller:sender: and, if horizontally compact, calls master view controller's -showviewcontroller:sender: method. uinavigationcontroller overrides -showviewcontroller:sender: , pushes incoming view controller onto navigation stack.

uitabbarcontroller not override -showviewcontroller:sender: , inherits default implementation presents incoming view controller modally. work around have subclass uitabbarcontroller , override -showviewcontroller:sender: forward tab bar controller's selectedviewcontroller if selectedviewcontroller navigation controller.

furthermore, when split view controller transitions compact horizontal size class regular horizontal size class, split view controller first sends -splitviewcontroller:separatesecondaryviewcontrollerfromprimaryviewcontroller: message delegate. delegate can implement method , handle separation itself, returning detail view controller. if delegate not implement method, or if implementation returns nil, split view controller sends -separatesecondaryviewcontrollerforsplitviewcontroller: message primary view controller. primary view controller should implement method handle separation. uinavigationcontroller implement -separatesecondaryviewcontrollerforsplitviewcontroller:. it's implementation pops top view controller off navigation stack , returns it. because using tab bar controller primary view controller, must implement -separatesecondaryviewcontrollerforsplitviewcontroller: , handle separation myself.

also need implement own collapsing logic. when split view controller transitions regular horizontal size class compact horizontal size class, split view controller first sends -splitviewcontroller:collapsesecondaryviewcontroller:ontoprimaryviewcontroller: message delegate. delegate can implement method , handle collapse itself. if delegate not implement method, split view controller sends -collapsesecondaryviewcontroller:forsplitviewcontroller: message primary view controller. primary view controller should implement method handle separation.

uinavigationcontroller implement -collapsesecondaryviewcontroller:forsplitviewcontroller:. it's implementation pushes secondary view controller onto navigation stack. because using tab bar controller primary view controller, must implement -collapsesecondaryviewcontroller:forsplitviewcontroller: , handle collapse myself.

try snippet , told results. snippet website outside stackoverflow (craig marvelley)

#pragma mark - split view // update secondaryview right screen - (uiviewcontroller *)splitviewcontroller:(uisplitviewcontroller *)splitviewcontroller separatesecondaryviewcontrollerfromprimaryviewcontroller:(uiviewcontroller *)primaryviewcontroller {  int tryit = 0;  if ((is_iphone_6_plus) && (islandscape)) {     if ([primaryviewcontroller iskindofclass:[uinavigationcontroller class]]) {         (uiviewcontroller *controller in [(uinavigationcontroller *)primaryviewcontroller viewcontrollers]) {             tryit = tryit + 1;             if ([controller iskindofclass:[uinavigationcontroller class]] && ([[(uinavigationcontroller *)controller visibleviewcontroller] iskindofclass:[yourposiblescreen01 class]] || [[(uinavigationcontroller *)controller visibleviewcontroller] iskindofclass:[yourposiblescreen02 class]]) ) {                 return controller;             }             // sublevel yo select right screen. must try number depends of how many internal hierarchy. believe need number 2 try :)              if (tryit > 2) {                 return controller;             }         }     }     // update detail screen     uiviewcontroller *toviewcontroller = [self.storyboard instantiateviewcontrollerwithidentifier:@"yourscreentoshow"];     return toviewcontroller; } return nil; }    - (bool)splitviewcontroller:(uisplitviewcontroller *)splitviewcontroller collapsesecondaryviewcontroller:(uiviewcontroller *)secondaryviewcontroller ontoprimaryviewcontroller:(uiviewcontroller *)primaryviewcontroller {       return no; } #pragma mark - split view 

Comments