【问题标题】:Split View App with Multiple Detail Views具有多个详细视图的拆分视图应用程序
【发布时间】:2014-08-09 20:39:11
【问题描述】:

我正在尝试创建具有多个详细视图控制器的拆分视图应用程序。我在应用程序的基本设置/骨架方面遇到问题。首先,我尝试使用 xcode 的 Master-Detail Application 模板。问题是模板中的类看起来像这样:

MasterViewController.h
MasterViewController.m
DetailViewController.h
DetailViewController.m

但我想要的是这样的:

MasterViewController.h
MasterViewController.m
TitleViewController.h
TitleViewController.m
DateViewController.h
DateViewController.m
...

当用户选择新行时,我不知道如何加载我的视图控制器。

我也尝试使用 Apple 提供的示例 MultipleDetailViews 应用程序,但该示例应用程序对我来说有多个问题,包括它使用了我不想要的 nib 文件这一事实。

有人可以帮忙吗?是否有一些关于如何设置具有多个详细视图控制器(没有笔尖)的拆分视图应用程序的教程?谢谢!

*回复:

谢谢!你能发布 BigNerdRanch 的链接吗?我找不到它。此外,我无法关注 Raywenderlich,因为它使用的是旧版本的 xcode。在您的示例项目之后,我想我已经接近了,但我得到了一个“以未捕获的异常终止......”。这是我所做的:

从主从模板创建新项目。 添加文件 MyTableViewController.h 和 MyTableViewController.m。 在 MasterViewController.m 中,将节数设置为 1,将行数设置为 2。 在 MasterViewController.h 添加属性“MyTableViewController *myTableViewController”。 (当用户单击第一行时,应该显示 detailViewController,当他单击第二行时,应该显示 myTableViewController。) 在 MasterViewController.m 中,将 didSelectRowAtIndexPath 更改为:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    int row = [indexPath row];

    if( row == 0 ) {
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.detailViewController];
        NSArray *vcs = [NSArray arrayWithObjects:[self navigationController],nav, nil];
        [[self splitViewController] setViewControllers:vcs];
    }
    else {
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.myTableViewController];
        NSArray *vcs = [NSArray arrayWithObjects:[self navigationController],nav, nil];
        [[self splitViewController] setViewControllers:vcs];
    }
}

项目运行,但是当我单击第二行(行 == 1)时出现异常。

*更新 2

- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
    int row = [indexPath row];

    AppDelegate *delegate = [[UIApplication sharedApplication] delegate];

    UINavigationController *detailNav = [delegate.splitController.viewControllers objectAtIndex: 1];
    NSArray *viewControllers = nil;
    switch (row) {
        case 0:
            viewControllers = [[NSArray alloc] initWithObjects: delegate.dateController, nil];
            break;
        case 1:
            viewControllers = [[NSArray alloc] initWithObjects: delegate.repeatController, nil];
        default:
            break;
    }

    [delegate.splitController removeFromParentViewController];
    detailNav.viewControllers = viewControllers;
    [delegate.window addSubview: delegate.splitController.view];
}

【问题讨论】:

  • 您真的应该在我的回答下发表评论。但是,是的,不要将 UINavigationController 换成新的 UINavigationController。一旦拆分 VC 被实例化,我不相信您可以将基本 VC 换成 splitViewController 中的另一个。使用作为 splitController 的基本 VC 之一的 navigationController,并设置 navigationController.viewControllers = @[newViewController1];。这应该够了吧。另外,不用担心老版本的Xcode,逻辑本质上还是一样的。
  • 我试图在您的回答下发表评论,但它不会格式化我的多行代码。无论如何,我不是 100% 确定你的意思。我现在正在使用我已经开始工作的 Raywenderlich 示例。在我的故事板中,层次结构看起来像:DetailVCNavVC-->MasterVC。我想在不更改任何其他内容的情况下交换 DetailVC,那么我将使用什么代码?谢谢。
  • 用 DetailVCNavVC-->MasterVC 代替你所拥有的。基本上,您将在两侧都有一个 NavigationController 并将其交换为 .viewControllers 数组。这样一来,splitViewController 就不会抱怨,因为它实例化的 viewController 总是在那里。 navControllers 只是作为一个基本的 VC 容器,可以交换它们的 viewControllers。
  • 好的,我按照你说的方式设置了结构。然后我将 didSelectRowAtIndexPath 更改为:(请参阅上面的更新)。代码似乎运行正确,但没有发生任何事情。然后我添加了删除和重新添加拆分VC视图到窗口的行,现在它可以工作了,但对我来说似乎不合适。为什么我必须删除并重新添加视图?
  • 此外,即使视图现在正在切换,它们也会横向进入。即使模拟器是横向的,它们也是纵向的。

标签: uisplitviewcontroller master-detail detailview


【解决方案1】:

BigNerdRanch 实际上有一个关于如何使用 UISplitViewControllers 的很棒的教程。老实说,使用它们将不同的 UIViewController 推送为 Detail 或 Master viewController 没有区别。它们只需要相互引用,当事件发生时,您将新的 viewController 推送到一侧或另一侧。我在下面附上了一个示例项目供您参考。

示例项目:link

这是另一个通过 Raywenderlich 设置的教程:link

【讨论】:

  • 示例项目链接已失效。
【解决方案2】:

所以以下发生在作为 MasterViewController 的 UITableViewController 中。

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            // 1. get the controllers from the split view [master, detail]
            let controllers = split.viewControllers
            
            // 2. get nav controller for the detail  + the current storyboard
            let navigationController = controllers[controllers.count-1] as!
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            
            // 3. create the appropriate view controller (vc) then just replace the navigation controllers root vc with your new one using 'navigationController.setViewControllers([vc] ...'
            switch indexPath.row {
            case 1:
                let vc = storyboard.instantiateViewController(withIdentifier: "DetailTableViewController") as! DetailTableViewController
                navigationController.setViewControllers([vc], animated: false)
            case 2:
                let vc = storyboard.instantiateViewController(withIdentifier: "DetailCollectionViewController") as! DetailCollectionViewController
                navigationController.setViewControllers([vc], animated: false)
            default:
                let vc = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
                navigationController.setViewControllers([vc], animated: false)
                break
            }
        }

你可以用 segues 做同样的事情。从情节提要的 MasterViewController 中,将 segue 拖到导航控制器并将 segue 类型设置为“显示详细信息(例如替换)”。然后从那里你 didSelectRowAt 你可以用标识符调用 performSegue 。确保你的 segue 有一个“标识符”

看看这个video

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    相关资源
    最近更新 更多