iPhone企业应用实例分析之四:技术要点分析(2)
1.表格控件定制
在iOS开发中,UITableView是使用频率最高的控件之一,为了实现各种用户界面的需要,经常需要对表格的每一行进行定制,如图5-14所示是文档历史的显示界面。

▲图5-14 文档历史界面
程序通过设置cell.textLabel.text和cell.detailTextLabel.text来达到如图5-14所示的显示效果,代码如下。
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *AttachmentsCell= @"HistoryCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
AttachmentsCell];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyle Value2
reuseIdentifier: AttachmentsCell] autorelease];
}
if(records != nil){
NSUInteger row = [indexPath row];
DocumentHistory *history = [records objectAtIndex:row];
cell.textLabel.text = history.historyText;
cell.detailTextLabel.text = history.historyTitle;
cell.detailTextLabel.numberOfLines = 2;
cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
}
return cell;
}
通常使用子类化UITableViewCell类的方法来定制表格控件,然后在UITableView进行表格绘制调用cellForRowAtIndexPath()时,使用该定制的子类呈现用户界面。在统计图列表的实现类StatisticsViewController中就使用了一个自定义的IndicatorSubviewCell类来定制每一行的显示,该类是UITableViewCell类的子类,如图5-15所示是统计图表格控件制作出来的效果图。

▲图5-15 统计图界面
IndicatorSubviewCell类使用.xib文件来创建界面显示内容,这样可以使用Interface Builder可视化地创建各种界面元素,Interface Builder提供了一个“Table View Cell”的设计控件,专门用来创建各种自定义表格控件,你只需要像使用普通View一样将需要的界面元素拖放进视图,并将其连接到相应的类成员即可,如图5-16所示是统计图表格控件在Interface Builder中的设计图。

▲图5-16 统计图控件设计界面
我们看到上面的设计视图包括两个UILabel和一个UIImageView,和上面的表格控件效果图并不一致,少了最右边的那个放大镜 图标,这是因为最后这个图标是一个可单击区域,用户单击这个区域以后程序显示具体的统计图,这个区域是由程序进行创建而不是通过Interface Builder可视化创建的,设计视图对应的类定义如下。
#import <Foundation/Foundation.h>
#import "IndicatorCell.h"
@interface IndicatorSubviewCell : UITableViewCell
{
IBOutlet UIImageView *iconView;
IBOutlet UILabel *nameLabel;
IBOutlet UILabel *priceLabel;
}
@end
…
2.自定义UIToolbar
在WebDoc Mobile项目中,程序使用自定义的UIToolbar来实现工作流设置的输入确认,虽然UIActionSheet类和UIToolbar类都可以提供带按钮的用户输入界面,但前者属于弹出式的模式窗口,而后者则是非弹出式的界面输入元素,工作方式不一样,因为在DocumentDetailViewController类中包含文档详情、文档附件、文档历史和工作流4个UISegmentedControl页面,“文档附件”页面需要提供UIToolbar按钮来引导用户浏览手机本地目录,以便选择需要上传的文件,“工作流”页面需要提供UIToolbar按钮来确认工作流设置,而其他两个页面不需要UIToolbar按钮,为了保持界面的一致性,程序通过用户当前选择的页面来判断是否该隐藏还是显示UIToolbar按钮,并根据不同页面做出不同的响应,如图5-17所示是带UIToolbar的工作流设置界面。

▲图5-17 自定义UIToolbar用户界面
在DocumentDetailViewController类的实现中,程序定义一个UIToolbar类成员变量,并在viewWillAppear函数中创建UIToobar对象,代码如下。
{
toolbar = [[UIToolbar alloc] init];
[self setNavigatinBarStyle:DEFAULT_STATUS_BAR_STYLE];
[toolbar sizeToFit];
CGFloat toolbarHeight = [toolbar frame].size.height;
CGRect rootViewBounds = self.parentViewController.view.bounds;
CGFloat rootViewHeight = CGRectGetHeight(rootViewBounds);
CGFloat rootViewWidth = CGRectGetWidth(rootViewBounds);
CGRect rectArea = CGRectMake(0, rootViewHeight - toolbarHeight, rootView Width, toolbarHeight);
[toolbar setFrame:rectArea];
[self.navigationController.view addSubview:toolbar];
if(self.segmentedControl != nil){
if(self.segmentedControl.selectedSegmentIndex == 1||
self.segmentedControl.selectedSegmentIndex == 3){
NSMutableArray* toolbarItems = [[NSMutableArray arrayWithArray: toolbar.items] retain];
int a = [toolbarItems count];
if (a == 0 ) {
infoButton = [[UIBarButtonItem alloc]
initWithTitle:@"AttachFile"
style:UIBarButtonItemStyleDone target:self action:@selector(browseFileSystem:)];
[toolbar setItems:[NSArray arrayWithObjects:infoButton,nil]];
}
self.navigationController.toolbarHidden = YES;
if(self.segmentedControl.selectedSegmentIndex == 3)
infoButton.title = @"Done";
else
infoButton.title = @"AttachFile";
}else{
self.navigationController.toolbarHidden = NO;
}
}else{
self.navigationController.toolbarHidden = NO;
}
}
程序在创建UIToolbar对象后,通过计算界面的宽度和高度,调用UIView的setFrame()方法将Toolbar放置在屏幕的最下方,并根据用户当前选择的UISegmentedControl页面,隐藏或者显示Toolbar,并在Toolbar上添加相应的按钮。