0

我在iPhone 6+支持狀態恢復的問題。iPhone 6+狀態恢復與主分離視圖中的標籤欄

這裏是我的層次: enter image description here

問題是,當狀態恢復發生在縱向方向,然後,在稍後的點,狀態解碼嘗試而在橫向方向做。

說明: 在縱向模式下,只有TabBar作爲主視圖(實際上,詳細視圖不存在),所以它被推送到TabBar導航的控制器中。

然後,在稍後的時候,當應用程序嘗試執行景觀狀態恢復時,我的詳細信息視圖會被推送到主導航控制器(詳細信息時)。

由於自定義層次結構,我相應地實現了UISplitViewControllerDelegate方法,並且它們工作正常。 UISplitViewControllerDelegate方法也確保狀態恢復工作在下列情況:

Landscape -> Landscape 
Landscape -> Portrait 
Portrait -> Portrait 

什麼不工作是:人像 - >風景,因爲,正如我所說,委託方法沒有得到時,在未摺疊狀態所謂視圖層次結構不知道如何從主視圖分割細節並將其嵌入到詳細導航控制器中。

回答

0

到目前爲止,我已經解決了這樣的問題:在viewWillAppear所有的細節控制器都從標籤欄的導航控制器中刪除。 當存儲狀態時,設備方向被保存並且SplitViewController.viewControllers(對我來說它不會像iOS7那樣自動存儲它們)。

- (void) encodeRestorableStateWithCoder:(NSCoder*)coder 
{ 
    [super encodeRestorableStateWithCoder:coder]; 
    [coder encodeObject:self.viewControllers forKey:@"viewControllers"]; 
    [coder encodeInteger:[UIApplication sharedApplication].statusBarOrientation forKey:@"orientation"]; 
} 

- (void) decodeRestorableStateWithCoder:(NSCoder*)coder 
{ 
    [super decodeRestorableStateWithCoder:coder]; 
    NSArray* viewControllers = [coder decodeObjectForKey:@"viewControllers"]; 
    if (viewControllers.count > 0) 
    { 
     self.viewControllers = viewControllers; 
    } 
    restoredOrientation = (UIInterfaceOrientation) [coder decodeIntegerForKey:@"orientation"]; 
} 

這裏是viewWillAppear中執行:

- (void) viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 

    // iPhone6+: if state restoration happened while in portrait orientation and app is launched while in landscape, 
    // then all detail views should be cut from master view and split details view is set appropriately 
    if (firstLoad && 
      [UIScreen mainScreen].scale > 2.9 && // assure it's iPhone 6+ 
      UIInterfaceOrientationIsPortrait(restoredOrientation) && 
      UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication.statusBarOrientation)) 
    { 
     UITabBarController* tbc = self.viewControllers[0]; 
     NSArray* detachedControllers = [tbc cutControllersFrom:DocumentViewController.class]; 
     if (detachedControllers.count > 0) 
     { 
      UINavigationController* documentNavigation = [self.storyboard 
        instantiateViewControllerWithIdentifier:@"NavigationController"]; 
      documentNavigation.viewControllers = detachedControllers; 
      self.viewControllers = @[ self.viewControllers[0], documentNavigation ]; 
     } 
     else // place some default no-selection controller in detail 
     { 
      UINavigationController* noSelectionNavigation = [self.storyboard 
        instantiateViewControllerWithIdentifier:@"NoSelectionSID"]; 
      self.viewControllers = @[ self.viewControllers.firstObject, noSelectionNavigation ]; 
     } 
    } 
    firstLoad = NO; 
} 

其中cutControllersFrom方法是對的UITabBarController類別:

- (NSArray*) cutControllersFrom:(Class)controllerClass 
{ 
    NSArray* ret; 
    for (UIViewController* vc in self.viewControllers) 
    { 
     if (![vc isKindOfClass:UINavigationController.class]) 
     { 
      continue; 
     } 

     UINavigationController* nc = (UINavigationController*) vc; 
     NSArray* removed = [nc cutFrom:controllerClass]; 
     if (vc == self.selectedViewController) 
     { 
      ret = removed; 
     } 
    } 

    return ret; 
} 

它調用cutFrom:方法是在UINavigationController的一個類別:

- (NSArray*) cutFrom:(Class)controllerClass 
{ 
    NSMutableArray* toRemove = [NSMutableArray array]; 
    BOOL startRemoving = NO; 
    UIViewController* endingViewController; 

    for (NSUInteger i = 0; i < self.viewControllers.count; i++) 
    { 
     UIViewController* vc = self.viewControllers[i]; 
     if ([vc isKindOfClass:controllerClass]) 
     { 
      startRemoving = YES; 
      endingViewController = self.viewControllers[i - 1]; 
     } 

     if (startRemoving) 
     { 
      [toRemove addObject:vc]; 
     } 
    } 
    if (endingViewController) 
    { 
     [self popToViewController:endingViewController animated:NO]; 
    } 

    return toRemove; 
} 
+0

似乎你沒有什麼選擇,並且在搞清楚所有這些方面做得很好。如果你想改變方法,一個選擇是不使用標籤欄並移動到側欄。我在我當前的應用程序中執行此操作,其中一個側面菜單允許我在多個分割視圖控制器之間切換好東西是每個分割視圖是分開的,並且具有用於主控和細節的導航控制器,因此更簡單。所以你的標籤欄可以成爲側欄菜單,讓你在4個分割視圖控制器之間切換:每個ControllerX一個。只是一個想法。 – 2015-02-26 23:39:59

+0

啊,是的,側面菜單是neet的想法。現在,我必須堅持使用TabBar,但爲了將來的參考,記住它是非常好的。 – mixtly87 2015-02-28 01:08:08

0

不知道我完全理解你的問題,因爲從肖像去風景在iPhone 6+應該從收縮狀態進入分裂狀態,所以應該把這種委託:

- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController

但是你似乎暗示這不是被稱爲的,在肖像中它處於非摺疊狀態?

在我使用的分體視圖控制器上,我發現最好讓控制器自行排除事情。如果你使用showDetail segues作爲細節視圖,它應該爲你處理分割。您是否確保使用showDetail segues從您的Controller1-> 4推送DetailController而不是顯示segse?

因此,假設您正在使用正確的細節到細節,只需在委託中返回nil以讓分割視圖控制器自行排序?

+0

如果master是UINavigationController,SplitViewController可以將事情整理出來,但在我的情況下,它是具有它自己的UINavigationControllers的UITabBarController,這是UISplitViewController不知道如何排序的東西,所以我必須通過實現UISplitViewControllerDelegate方法手動執行。 – mixtly87 2015-02-25 14:30:55

+0

好的。也許你需要在你的分割視圖控制器中實現' - splitViewController:showDetailViewController:sender:'來讓你把細節放在正確的位置? – 2015-02-25 14:58:07

+0

我已經實現了這個方法,但是那個並沒有被調用狀態恢復。 – mixtly87 2015-02-26 17:37:53