【问题标题】:different initial viewcontroller不同的初始视图控制器
【发布时间】:2014-05-21 03:23:50
【问题描述】:

我正在构建一个应用程序,用户可以在其中从另一个 ViewController 中选择一个项目,然后打开一个拆分 ViewController。我发现我无法将另一个 ViewController 设置为初始值,但我已经找到了第二个解决方案。

我将拆分视图设置为初始视图,并在 viewDidAppear 方法上导航到假初始 ViewController,就好像它是初始的一样。然后将选定的项目设置在全局变量中,并像这样关闭项目页面:

[self dismissModalViewControllerAnimated:YES]

打开splitview

我的问题: 我可以使用这种方法吗?如果应用按预期运行,苹果会批准吗?

谢谢!

编辑

这段代码在我的AppDelegate.m里,应该改成什么?

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UISplitViewController *splitviewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitviewController.viewControllers lastObject];
splitviewController.delegate = (id)navigationController.topViewController;
return YES;
}

编辑 2:

// Override point for customization after application launch.
UISplitViewController *splitviewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitviewController.viewControllers lastObject];
splitviewController.delegate = (id)navigationController.topViewController;

如何将 self.window.rootViewController 引用到 SplitViewController?这样它就不会认为这个视图控制器会“托管”拆分视图?

编辑 3:

// Close the ProjectsViewController and open the selected project
[self presentViewController:_detailViewController animated:YES completion:^{
    [[[[UIApplication sharedApplication] delegate] window] setRootViewController:_detailViewController];
}];

编辑 4:

* 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“应用程序试图以模态方式呈现拆分视图控制器

方法与按钮链接:

-(void)selectedProject {
// The user opened a project

// Override point for customization after application launch.
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; // assuming your split view controller in storyboard with name "Main" in project's main bundle
UIViewController *splitViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"splitVC"];

UISplitViewController *splitviewController = (UISplitViewController *)splitViewController;
UINavigationController *navigationController = [splitviewController.viewControllers lastObject];
splitviewController.delegate = (id)navigationController.topViewController;

// Close the ProjectsViewController and open the selected project
[self presentViewController:splitViewController animated:YES completion:^{
    [[[[UIApplication sharedApplication] delegate] window] setRootViewController:splitViewController];
}];
}

显示项目页面:

- (IBAction)closeProject:(id)sender {
// Show the selectSubjectBanner
_selectSubjectBanner.hidden = NO;

// Save the current subject in case the user edited it
[self saveCurrentSubject];

// Present the ProjectsViewController
[self performSegueWithIdentifier:@"projectsSegue" sender:nil];
}
}

关闭项目页面:

- (void)selectedProject {
// The user opened a project

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; // assuming your split view controller in storyboard with name "Main" in project's main bundle
UISplitViewController *splitViewController = (UISplitViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"splitVC"];

UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;

// Close the ProjectsViewController and open the selected project
[UIView transitionFromView:[[[[[UIApplication sharedApplication] delegate] window] rootViewController] view]
                    toView:splitViewController.view
                  duration:0.5
                   options:UIViewAnimationOptionTransitionFlipFromLeft
                completion:^(BOOL finished) {
                    [[[[UIApplication sharedApplication] delegate] window] setRootViewController:splitViewController];
                }];
}

【问题讨论】:

  • 这不是一个好方法,因为即使你将用户发送到一个假的 viewController,它也会注意到你在另一个 viewController 加载后改变了
  • 你能更好地解释你的问题吗?为什么你说你不能将其他视图控制器设置为初始?任何视图控制器都可以是初始视图控制器。此外,对您希望实现的架构进行更深入的解释将对任何希望帮助您的人有所帮助。
  • 嗯。你知道解决这个问题的好方法吗?
  • 拆分视图控制器具有故事板的首字母 - 认为文档说明了这一点。我希望用户从视图控制器中选择一个项目,然后将其发送到一个新的视图控制器 - splitviewcontroller。
  • 据我所知,Apple 的文档曾经说过拆分视图控制器必须是根视图控制器(不一定是初始控制器)。但这一限制已被取消。 Take a look to the docs your self.

标签: ios objective-c uiviewcontroller uisplitviewcontroller


【解决方案1】:

最好设置窗口的rootViewController

[[[[UIApplication sharedApplication] delegate] window] 
                     setRootViewController:yourViewController];

编辑:这是如何从情节提要中实例化视图控制器的代码,

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; // assuming your split view controller in storyboard with name "Main" in project's main bundle
UIViewController *splitViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"splitVC"];

确保在 Storyboard、Identity Inspector 选项卡、splitVC(例如)中为视图控制器设置 Storyboard ID

编辑: 所以,UISplitViewController 本身就是一个容器视图控制器,因此我们不能在 UINavigationController、UITabBarController、add as childViewController、.. 等中保存它。而且我们也不能呈现它模态的,因此我们没有得到动画演示。 UISplitViewController 应该是窗口的rootViewController。在 rootViewController 和 splitViewController 之间获得动画转换的最简单方法是使用 UIView 的 transitionFromView 类方法并在视觉上交换它们的视图,同时更改 rootViewController 属性。这是您编辑的代码。

- (void)selectedProject {
    // The user opened a project

    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; // assuming your split view controller in storyboard with name "Main" in project's main bundle
    UISplitViewController *splitViewController = (UISplitViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"splitVC"];

    UINavigationController *navigationController = [splitviewController.viewControllers lastObject];
    splitViewController.delegate = (id)navigationController.topViewController;

    // Close the ProjectsViewController and open the selected project
    [UIView transitionFromView:[[[[[UIApplication sharedApplication] delegate] window] rootViewController] view]
                        toView:splitViewController.view
                      duration:0.5
                       options:UIViewAnimationOptionTransitionFlipFromLeft
                    completion:^(BOOL finished) {
                        [[[[UIApplication sharedApplication] delegate] window] setRootViewController:splitViewController];
                    }];
}

【讨论】:

  • 然后我可以像普通视图控制器一样以模态方式推送到拆分视图?你确定这会起作用吗?
  • 在这种情况下,“yourViewController”成为初始视图控制器并立即出现,没有动画
  • 好的,所以我使用你的解决方案 - 像我的一样工作,没有动画 - 然后我可以从“yourViewController”模态到拆分视图?
  • 那么这似乎是最合适的。但是委托中的其他代码设置拆分视图 - 怎么样?
  • 如果你打算使用“-presentModalViewController:animated:”和“dismissModalViewControllerAnimated”,请注意这些方法自 iOS 6 起已弃用,而不是使用“-presentViewController:animated:completion:”和“dismissViewControllerAnimated” :完成:“。祝你好运!
【解决方案2】:

您可以将任何视图控制器设置为初始视图控制器

您不能在 viewDidAppear 方法中启动视图控制器。太糟糕了。

在考虑应用转换时,Apple 不会拒绝应用。这取决于开发人员。

您可以通过重置窗口的rootviewcontroller来设置任何viewcontroller

而不是故事板检查您的逻辑并从 appdelegate 启动必要的视图控制器。分别替换Seryozha提到的窗口rootViewController

【讨论】:

  • 我设法将另一个 viewcontrollerr 显示为初始值,但问题是模态到拆分视图 - 我该怎么做?
  • 您应该创建一个 splitviewcontroller 对象,然后将其呈现给 viewcontroller。或者只是替换窗口rootviewcontroller。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多