• 创建基于主-从视图的应用程序(Master-Detail Application)


    以Master-Detail Application创建的应用程序在iPad和iPhone上都能运行,虽然模板解决了大部分问题,但还是有一些Apple遗留问题需要解决。使用该模板创建项目时,需要将下拉列表Device Family设置为Universal,且不要选择复选框Use Core Data。

    项目默认就包含两个故事板,一个用于iPhone(MainStoryboard_iPhone.storyboard),另一个用于iPad(MainStoryboard_iPad.storyboard)。

    打开MainStoryboard_iPad_storyboard,可以看到一个分割视图控制器连接到两个导航控制器(UINavigationController)。主导航控制器连接到一个包含表视图(UITableView)的场景,这是主场景,由MasterViewController类处理;详细信息导航控制器连接到一个简单的空场景(UIViewController),由DetailViewController类处理。

    MainStoryboard_iPhone.storyboard就简单许多,一个导航控制器(UINavigationController)连接到两个场景。第一个是主场景(MasterViewController),第二个是详细信息场景(DetailViewController)。

    需要注意的一个细节是:在iPhone故事板下,如果你修改主场景里的UITableView,将Content由默认的值Static Cells改为Dynamic Prototypes,修改完成后会丢失主场景到详细信息场景的连接。要修复该连接,需要按住Control键,并从单元格(不是表)拖曳到详细信息场景,并在Xcode提示时选择Push。

    无论是iPhone还是iPad故事板,基本的流程是一样的:
    step 1: 主场景包含一个UITableView,并加载数据。
    step 2: 点击某一个Cell,将Cell包含的数据对象传递给详细信息场景,并跳转或加载详细信息场景。
    step 3: 详细信息场景加载后,根据接收到的Cell数据对象做相应的初始化工作。

    对于step1,主要还是实现表视图的数据源协议(UITableViewDataSource)要求的主要方法,这一步和以前单独实现表视图的方法完全一致。

    step2主要处理表视图的委托协议(UITableViewDelegate)的tableView:didSelectRowAtIndexPath:方法。当收集到Cell的数据对象后,将该对象传给详细信息场景。可能的代码如下:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        self.detailViewController.detailItem = [[flowerData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    }

    step3是当详细信息场景加载后,通过一个名为configureView的方法,来获取step2设置的detailItem,并做相应处理。可能的代码如下:

    - (void)configureView
    {
        // Update the user interface for the detail item.
    
        if (self.detailItem) 
        {
            NSDictionary *dict = self.detailItem;
            
            self.navigationItem.title = [dict objectForKey:@"name"];
            
            NSURL *url = [NSURL URLWithString:[dict objectForKey:@"url"]];
            NSURLRequest *request = [NSURLRequest requestWithURL:url];
            [self.detailWebView loadRequest:request];
            
            self.detailDescriptionLabel.hidden = YES;
        }
    }

    一般做到上面三步,应用程序在iPad上就能正常运行了;但其iPhone版存在一个小问题,就是在用户点击Cell时,并不能直接获取详细信息场景的对象,可以用下面的代码验证:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(self.detailViewController)
        {
            NSLog(@"i got it");
        }
        else
        {
            NSLog(@"bad luck,it's nil");
        }
    }

    在iPhone下self.detailViewController得到的是一个nil,而在iPad下可以正确获取到对象,这是因为iPad是由分割视图控制器管理,可以轻松访问另一个场景的视图控制器。要修复这种问题,在iPhone中需要先在prepareForSegue:sender:方法中设置self.detailViewController的值:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        self.detailViewController = segue.destinationViewController;
    }

    当这样设置以后,应用程序在iPad和iPhone上就都能正常运行了。总的来说,基于Master-Detail Application来创建项目还是比较简单的,只需要注意iPhone版会遇到的两个问题就OK了(1. 改表视图的Content导致的连接丢失;2. self.detailViewController为nil)。

  • 相关阅读:
    Python 读取二进制、HTML 、XML 格式存储的 Excel 文件
    ios自动将长数字(7位)转成电话号码
    前端常见手撕源码
    在微信里及QQ浏览器里ios短信回填vue方法取不到值,去除黄色背景
    js添加css到head中
    WEB 基础认证(BasicAuth)
    Word如何插入PDF格式矢量图片
    【解决】MATLAB中报错:无法将双精度值 0.0401495 转换为句柄
    【解决】Word中插入图片后变模糊
    使用SuperSocket开发联网斗地主(三):抢地主
  • 原文地址:https://www.cnblogs.com/CoderWayne/p/3596818.html
Copyright © 2020-2023  润新知