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
Post a Comment