創建基於主-從視圖的應用程序(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)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM