iPad开发:UISplitViewController应用

鉴客 发布于 2012/01/09 17:44
阅读 3K+
收藏 0

iPad 应用中,UISplitViewController是最具特色的视图控制器,用于显示一个从左右分隔的分栏视图。

新建 View–based Appliation项目:SplitVCDemo。用IB打开SplitVCDemoViewController.xib,点击 File->CreateiPad Version Using…,save as,文件名仍保持“SplitVCDemoViewController.xib”不变,覆盖:replace。

从Library窗口拖一个SplitView Controller到Document窗口。

可以看到,Split View Controller已有一个Navigation Controller和一个View Controller对象了。在NavitationController下边还有一个Table View Controller对象,这是用于显示Split View Controller左边的列表的控制器,是整个SplitView Controller 中最核心的部分,我们接下来要实现它。

现在,新建一个Table View Controller 子类RootVC,不要选择With Xib for user interface,RootVC是用来导航ViewController的,它不需要一个.xib文件。

我们先打开RootVC.h文件,声明几个变量:

UISplitViewController *splitViewController;

   

    UIPopoverController *popoverController;   

    UIBarButtonItem *rootPopoverButtonItem;

 

同时属性声明:

@property (nonatomic, assign) IBOutlet UISplitViewController*splitViewController;

 

@property (nonatomic, retain) UIPopoverController*popoverController;

@property (nonatomic, retain) UIBarButtonItem *rootPopoverButtonItem;

回到SplitVCDemoViewController.xib中,把TableView Controller对象的类别Identity修改为RootVC。

建立连接,将RootVC中的splitViewController和IB对象SplitView Controller连接起来:

同时,将 Split View Controller 的delegate属性和RootVC连接起来:

这样就把 Split View Controller 的一些事件委托给RootVC来实现,这需要RootVC实现协议UISplitViewControllerDelegate。在RootVC.h中声明协议实现,然后在RootVC.m中进行实现:

#pragma mark -

#pragma mark 旋屏支持及UISplitViewControllerDelegate协议实现

// 支持旋屏

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

    return YES;

}

// 当splitViewController旋转为竖屏时,左边栏隐藏,同时显示一个工具栏按钮,用于一个PopOver Controller弹出左边栏

- (void)splitViewController:(UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItemforPopoverController:(UIPopoverController*)pc {

   

    // 从参数获得按钮和popover controller的引用.

    barButtonItem.title = @"Root View Controller";

    self.popoverController =pc;

    self.rootPopoverButtonItem =barButtonItem;

// 获取右边栏,在右边栏中显示按钮

    UIViewController<SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];

   [detailViewController showRootPopoverButtonItem:rootPopoverButtonItem];

}

// 当split View controller旋转为横屏,左边栏显示,同时消除popover按钮

- (void)splitViewController:(UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem*)barButtonItem {

UIViewController<SubstitutableDetailViewController> *detailViewController = [splitViewController.viewControllers objectAtIndex:1];

// SubstituableDetailViewController协议规定了两个方法,分别用于显示/清除popover按钮

    [detailViewControllerinvalidateRootPopoverButtonItem:rootPopoverButtonItem];

    // 释放

self.popoverController =nil;

    self.rootPopoverButtonItem =nil;

}

 

当屏幕竖屏显示时,Split View Controller会隐藏左边栏而只显示右边栏,为了让用户能看到左边栏,我们需要在右边栏的工具条上显示一个popover按钮。这样,在左边栏不显示的情况下,用户可以通过点击这个popover按钮来弹出显示左边栏的内容。为此,我们在RootVC.h中定义了一个协议 SubstitutableDetailViewController,要求在必要的时候右边栏能实现popover按钮的显示方法和消除方法:

@protocolSubstitutableDetailViewController

- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;

- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;

@end

接下来就是实现UITableView的UITableViewDataSource协议和UITableViewDelegate协议。这都是大家都熟悉的内容了:

#pragma mark -

#pragma mark Tableview data source method

 

- (NSInteger)tableView:(UITableView *)aTableViewnumberOfRowsInSection:(NSInteger)section {

     return 2;

}

 

 

- (UITableViewCell *)tableView:(UITableView *)aTableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath {

   

    static NSString *CellIdentifier = @"RootViewControllerCellIdentifier";

    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    }

    if (indexPath.row == 0) {

       cell.textLabel.text = @"First DetailView Controller";

    }

    else {

       cell.textLabel.text = @"Second DetailView Controller";

    }

    return cell;

}

 

 

#pragma mark -

#pragma mark Tableview delegate method

 

- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath *)indexPath {

NSUInteger row = indexPath.row;

   

    UIViewController <SubstitutableDetailViewController>*detailViewController = nil;

    if (row == 0) {

        detailViewController= [[DetailVC alloc] initWithNibName:@"DetailVC" bundle:nil];

[detailViewController.view setBackgroundColor:[UIColor redColor]];

    }

    if (row == 1) {

       detailViewController = [[DetailVC alloc] initWithNibName:@"DetailVC" bundle:nil];

[detailViewController.view setBackgroundColor:[UIColor blueColor]];

    }

    // 修改 split view controller的viewControllers属性.

    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController,detailViewController, nil];

    splitViewController.viewControllers =viewControllers;

   [viewControllers release];

   

    // 如果popover窗口在弹出中,解散

    if (popoverController!= nil) {

        [popoverController dismissPopoverAnimated:YES];

    }

    // 重新设置右边栏的popover按钮

    if (rootPopoverButtonItem!= nil) {

        [detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];

    }

    [detailViewControllerrelease];

}

 

接下来我们实现右边栏的视图控制器。你可以实现多个View Controller,但为求简便。我们只实现一个。在 tableViewv:didSelectRowAtIndexPath:代码中,你可以看到针对每一行的点击,我们都new了一个DetailVC对象作为右边栏的View Controller。如果你愿意,你也可以针对每一行的点击new不同ViewController类作为右边栏。这样,自然就能通过左边的列表导航到多个Detail View Controller了。

新建View Controller类DetailVC,这次需要一个.xib文件。 打开DetailVC.h,增加变量声明:

UIToolbar *toolbar;

将变量声明为出口:

@property (nonatomic, retain) IBOutlet UIToolbar *toolbar;

然后,在DetailVC.m中实现以下方法:

#pragma mark SubstitutableDetailViewController协议实现

 

- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem {

   

    // Add the popover button to the toolbar.

    NSMutableArray*itemsArray = [toolbar.items mutableCopy];

    [itemsArray insertObject:barButtonItem atIndex:0];

    [toolbar setItems:itemsArray animated:NO];

    [itemsArray release];

}

- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem*)barButtonItem {

   

    // Remove the popover button from the toolbar.

    NSMutableArray *itemsArray= [toolbar.items mutableCopy];

    [itemsArray removeObject:barButtonItem];

    [toolbar setItems:itemsArray animated:NO];

    [itemsArray release];

}

 

#pragma mark 旋屏支持

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

    return YES;

}

 

打开DetailVC.xib文件,将其转换为iPad版本。然后拖一个Tool Bar在视图中,并把Tool Bar连接到出口IBOutlettoolbar。

回到SplitVCDemoViewController.xib,把View Controller对象的类别Identity修改为DetailVC:

这样并不能就显示出Split View Controller来,因为Split View Controller还没有把视图addSubview到视图控制器的view中。

首先我们要在SplitVCDemoViewController.h中声明一个出口用于连接Split View Controller对象:

SplitVCDemoViewController *viewController;

⋯⋯

@property (nonatomic, retain) IBOutletSplitVCDemoViewController *viewController;

然后,回到SplitVCDemoViewController.xib,把IB对象Split View Controller连接到出口viewController。

然后在SplitVCDemoViewController.m的viewDidLoad方法中,我们可以加载Split ViewController了:

- (void)viewDidLoad {

// [self.view addSubview:splitVC.view];

//Split View Controller 只能作为window的根视图控制器

UIWindow* window=[(SplitVCDemoAppDelegate*)[[UIApplication sharedApplication]delegate]window];

window.rootViewController=splitVC;

}

这里需要说明一点,要把Split View Controller添加到视图中,你不能使用UIView或者UIWindow的addSubview方法。这个问题说起来很简单,但网络上并没有正确的答案,许多解决思路都没有说在点子上。

苹果文档中说明,Split View Controller只能作为应用程序Window的根视图控制器使用, 很多程序员都在为Split ViewController只能作为根视图控制器的问题而烦扰,实际上解决的办法是如此简单:

我们直接获取到应用程序委托的window对象,把它的rootViewController属性设置为Split View Controller实例就可以了(原来是这个属性被设置为SplitVCDemoViewController实例对象)。

现在,我们可以运行程序了。模拟器开始总是竖屏启动的,这时没有左边的列表栏。但工具栏上有一个popover按钮,点击它列表栏以弹出方式显示:

文章出处:http://blog.csdn.net/kmyhy/article/details/6908092

加载中
返回顶部
顶部