20

ストーリーボードを使用するIOS5.1Webクライアントアプリを構築しています。私のアクションの1つは「ログアウト」です。この間、ルートビューをストーリーボードのルートビューによって作成された初期ビューにリセットします。(ログインすると、ユーザーに基づいて一部のビューアイテムが削除または追加されます。ログアウトすると、ストーリーボードで指定したデフォルト値にリセットします。)

プログラムですべての要素をリセット/再追加できることに気付きましたが、ストーリーボードはどのように優れていますか?ビューファイルをリロードすることで、正方形に戻す方法が必要だと思いますよね?

4

3 に答える 3

28

私は次のアプローチが私のために働くことを発見しました。私はARCを使用していることに注意してください。ただし、これがソリューションに大きな影響を与えるかどうかはわかりません。まず、アプリデリゲートクラスでapplication:didFinishLaunchingWithOptions:、次のコード行を使用して最初のストーリーボードインスタンスをキャプチャします。

_initalStoryboard = self.window.rootViewController.storyboard;

(明らかにインスタンス変数がありますUIStoryboard* _initalStoryboard;

次に、アプリデリゲートで次の関数を定義します。

- (void)resetWindowToInitialView
{
    for (UIView* view in self.window.subviews)
    {
        [view removeFromSuperview];
    }

    UIViewController* initialScene = [_initalStoryboard instantiateInitialViewController];
    self.window.rootViewController = initialScene;
}

からすべてのサブビューを削除するforinループに注意してくださいwindow。UIWindowrootViewControllerのドキュメントには次のように記載されています。

ウィンドウに既存のビュー階層がある場合、新しいビューがインストールされる前に古いビューが削除されます。

ただし、これが当てはまるとは思わなかったので、新しいrootViewControllerを割り当てる前に、既存のビューを自分で明示的に削除します。この方法を使用しても、心配な副作用やメモリリークは見つかりませんでした。私は決してUIKitの魔法の専門家ではないので、自分で使用する予定がある場合は、このソリューションをテストして再テストすることをお勧めします。乾杯

于 2012-09-10T04:39:47.867 に答える
2

NavControllerベースの構造を使用する場合、以下は私にとって最適です。

UIWindow *window = [[UIApplication sharedApplication].windows firstObject];
UINavigationController *navController = (UINavigationController *)window.rootViewController;
UIViewController *vc = [navController.storyboard instantiateViewControllerWithIdentifier:@"Login"];
navController.viewControllers = @[vc];

これを機能させるには、ストーリーボードID「ログイン」をログインVCに割り当てる必要があります。

于 2014-08-23T18:49:25.640 に答える
0

UISplitViewControllerベースの構造(iOS 8以降でテスト済み)を使用している場合、次のように機能します。

Projects General-> Deployment Infoからストーリーボードを削除ますドロップダウンは次のようになり、コードでストーリーボードを構成する必要があります。

展開情報空のメインインターフェイス

どこかでAppDelegate.m

- (void)setupViewControllers
{
    // check for thread, as this method might be called by other (e.g. logout) logic
    if ([NSThread currentThread] != [NSThread mainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self setupViewControllers];
        });
        return;
    }

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    UIViewController *vc =[storyboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = vc;

    // configure split vc 
    // Note: I reference split vc for my own purpose, but it is your mater of choice
    self.splitViewController = (UISplitViewController *)self.window.rootViewController;
    self.splitViewController.delegate = self;
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
    self.splitViewController.preferredPrimaryColumnWidthFraction = 0.5;

    [self.window makeKeyAndVisible];
}

コードの重複を避けるためapplication:didFinishLaunchingWithOptions:に、初めてのセットアップとしてこの関数を呼び出します

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // some code...
    [self setupViewControllers];
    // Optional: add splash view (e.g. [self addSplashView];)
    // some code...
}

ビューコントローラ内で、スプラッシュビューを削除してユーザーにUIを表示する準備が整いました。例(Swiftの場合):

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    if !AppSession.currentSession().isLoggedIn() {
        presentLoginViewController(false, completion: { ()->Void in
            self.removeSplash()
        })
    }
    else {
       removeSplash()
    }

    // some code...
}

private func removeSplash() {
    if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
        appDelegate.removeSplashView()
    }
}
于 2015-11-24T10:06:18.170 に答える