簡體   English   中英

使用帶有TabBarController的多個故事板

[英]Using multiple storyboards with a TabBarController

好吧,所以在開發我的最新應用程序的過程中,我發現我的storyboard變得龐大,所以為了清理它,我把它分成multiple storyboards然后才失控。 僅僅為了設置我有大約20個tableviewcontrollers從根NavigationController分支出來。 那個navigationcontrollerTabBarController上的一個TabItem,它是application's根視圖控制器。

我已將TabBar移動到它自己的StoryBoard作為Root_Storyboard ,導航控制器現在是Settings_Storyboard的初始視圖。

僅出於測試目的,我在TabBarController (Root_Storyboard)中放置了一些UIViewControllers作為選項卡項,並將其子類化為一個,並將以下代碼添加到它的viewWillAppear方法中。 它工作得很好,但我知道presentViewController以模態presentViewController顯示NavigationController並隱藏tabBar 顯然我不想那樣,我怎樣才能讓它正確推動以便TabBar保持可見?

- (void) viewWillAppear:(BOOL)animated {
UIStoryboard *settingsStoryboard = [UIStoryboard storyboardWithName:@"Settings_iPhone" bundle:nil];
UIViewController *rootSettingsView = [settingsStoryboard instantiateInitialViewController];

[self.tabBarController presentViewController:rootSettingsView animated:NO completion:NULL];
}

編輯 - 澄清。 上面的代碼是Root_iPhone.storyboard中UIViewController (child of UITabBarController:index(1))的子類方法。 我試圖加載的UINavigationController/UITableViewController可以在Settings_iPhone.storyboard找到。 在這種情況下,不確定如何實現下面建議的linkView。

這是非常可能的,一個聰明的舉動 - 整理你的故事板提供了更清晰的界面文件,可以深入挖掘,減少XCode的加載時間,以及更好的組編輯。

我已經在Stack Overflow上梳理了一段時間,並注意到每個人都采用自定義分段或以編程方式實例化基於選項卡的設置。 讓人驚訝。 我已經破解了一個簡單的UIViewController子類,您可以將其用作故事板的占位符。

碼:

頭文件:

#import <UIKit/UIKit.h>

@interface TVStoryboardViewController : UIViewController

@end

實施文件:

#import "TVStoryboardViewController.h"



@interface TVStoryboardViewController()

@property (nonatomic, strong) UIViewController *storyboardViewController;

@end



@implementation TVStoryboardViewController



- (Class)class { return [self.storyboardViewController class]; }

- (UIViewController *)storyboardViewController
{
    if(_storyboardViewController == nil)
    {

        UIStoryboard *storyboard = nil;
        NSString *identifier = self.restorationIdentifier;

        if(identifier)
        {
            @try {
                storyboard = [UIStoryboard storyboardWithName:identifier bundle:nil];
            }
            @catch (NSException *exception) {
                NSLog(@"Exception (%@): Unable to load the Storyboard titled '%@'.", exception, identifier);
            }
        }

        _storyboardViewController = [storyboard instantiateInitialViewController];
    }

    return _storyboardViewController;
}

- (UINavigationItem *)navigationItem
{
    return self.storyboardViewController.navigationItem ?: [super navigationItem];
}

- (void)loadView
{
    [super loadView];

    if(self.storyboardViewController && self.navigationController)
    {
        NSInteger index = [self.navigationController.viewControllers indexOfObject:self];

        if(index != NSNotFound)
        {
            NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
            [viewControllers replaceObjectAtIndex:index withObject:self.storyboardViewController];
            [self.navigationController setViewControllers:viewControllers animated:NO];
        }
    }
}

- (UIView *)view { return self.storyboardViewController.view; }



@end

描述:

  1. 視圖控制器使用其恢復標識符來實例化項目中的故事板。
  2. 加載后,它將嘗試使用Storyboard的初始視圖控制器在其UINavigationController的viewController數組中替換自身。
  3. 請求時,此子類將返回Storyboard的初始視圖控制器的UINavigationItem。 這是為了確保加載到UINavigationBars中的導航項與交換后的視圖控制器相對應。

用法:

要使用它,請將它指定為屬於UINavigationController的Storyboard中的UIViewController的子類。

在此輸入圖像描述

為它分配一個恢復ID,你很高興。

在此輸入圖像描述

建立:

以下是您在Storyboard中設置的方式:

圖顯示設置

此設置顯示標簽欄控制器,其中導航控制器作為其第一個標簽控制器。 每個導航控制器都有一個簡單的UIViewController作為其根視圖控制器(我已經將UIImageViews添加到占位符中,以便於記住它鏈接到的內容)。 它們中的每一個都是TVStoryboardViewController的子類。 每個都有一個恢復ID設置為他們應鏈接到的故事板。

有些勝利:

  • 它似乎最適用於模態演示,其中子類是導航控制器的根視圖控制器。
  • 子類不會推送堆棧上的任何控制器 - 它交換。 這意味着您不必手動隱藏后退按鈕或覆蓋其他位置的選項卡行為。
  • 如果您雙擊選項卡,它將按照預期將您帶到Storyboard的初始視圖(您將不會再次看到該占位符)。
  • 設置超級簡單 - 沒有自定義segues或設置多個子類。
  • 您可以將UIImageViews和您喜歡的任何內容添加到占位符視圖控制器中,以使您的故事板更清晰 - 它們永遠不會顯示。

一些限制:

  • 該子類需要屬於鏈中某處的UINavigationController。
  • 此子類僅實例化Storyboard中的初始視圖控制器。 如果要在鏈中進一步實例化視圖控制器,可以始終進一步拆分故事板並重新應用此子類技巧。
  • 推送視圖控制器時,此方法無法正常工作。
  • 當用作嵌入式視圖控制器時,此方法不能很好地工作。
  • 通過segue傳遞的消息可能不起作用。 這種方法適合於界面部分是唯一的,不相關的部分(以模態或通過標簽欄呈現)的設置。

這種方法被黑客攻擊以解決這個UITabBarController問題,因此將其用作更大問題的部分解決方案。 我希望Apple能夠改進“多故事板”支持。 但是對於UITabBarController設置,它應該是一種享受。

對於Hawke_Pilot來說這有點晚了,但它可能對其他人有所幫助。

從iOS 9.0開始,您可以創建一個關系Segue到另一個故事板。 這意味着標簽欄視圖控制器可以鏈接到另一個故事板上的視圖控制器,而不會在其他答案中看到一些令人費解的技巧。 :-)

但是,僅此一點無濟於事,因為其他故事板中的收件人不知道它被鏈接到選項卡欄視圖控制器,並且不會顯示選項卡欄進行編輯。 將Storyboard參考指向所需的View Controller后,您只需選擇Storyboard Reference並選擇Editor-> Embed In-> Navigation Controller。 這意味着導航控制器知道它鏈接到標簽欄視圖控制器,因為它位於同一個故事板上,並將在底部顯示標簽欄並允許編輯按鈕圖像和標題。 無需代碼。

不可否認,這可能不適合所有人,但可能會為OP工作。

不確定您的問題是否得到解答,並且對於尋找此問題的解決方案的其他人,請嘗試此方法。

在此輸入圖像描述

  1. 在一個故事板文件中創建帶有導航控制器的選項卡欄控制器。 並添加一個空視圖控制器(我將其命名為RedirectViewController),如圖所示。
  2. 子視圖控制器(我們稱之為SettingsViewController為您的案例)位於Settings_iPhone.storyboard中。
  3. 在RedirectViewController.m中,代碼為:

     - (void)viewWillAppear:(BOOL)animated { UIStoryboard *settingsStoryboard = [UIStoryboard storyboardWithName:@"Settings_iPhone" bundle:nil]; UIViewController *rootSettingsView = [settingsStoryboard instantiateInitialViewController]; [self.navigationController pushViewController:rootSettingsView animated:NO completion:nil]; } 
  4. 觸摸“設置”選項卡后,SettingsViewController將立即進入視圖。
  5. 解決方案尚未完成! 您將在SettingsViewController上看到“<Back”作為左側navigationItem。 viewDidLoad方法中使用以下行:

     self.navigationItem.hidesBackButton = YES; 
  6. 此外,為了防止相同的標簽欄項被輕擊並導致跳回到空白的rootViewController,目標視圖控制器將需要實現UITabBarControllerDelegate

     - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { return viewController != tabBarController.selectedViewController; } 

這個對我有用。

將以下代碼添加到LinkViewController

-(void) awakeFromNib{
    [super awakeFromNib];
    ///…your custom code here ..

    UIStoryboard * storyboard = [UIStoryboard storyboardWithName:self.storyBoardName bundle:nil];
    UIViewController * scene = nil;

    // Creates the linked scene.
    if ([self.sceneIdentifier length] == 0)
        scene = [storyboard instantiateInitialViewController];
    else
        scene = [storyboard instantiateViewControllerWithIdentifier:self.sceneIdentifier];
        if (self.tabBarController)
            scene.tabBarItem = self.tabBarItem;
    }

這是LinkViewController的screenShot 截圖

LinkViewController只是一個占位符,可以放置新的viewController。 這是我用於我的應用程序的示例代碼。

RBStoryboardLink 它對我很有用。 如果它對您有幫助,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM