本节书摘来自异步社区《iPad开发从入门到精通》一书中的第6章,第6.6节系统设置,作者 杨春泽,更多章节内容可以访问云栖社区“异步社区”公众号查看
6.6 系统设置
iPad开发从入门到精通
为了方便用户对本系统的管理,特意提供了本模块供用户对系统进行管理。主要包括如下所示的功能。
主题设置。
当前城市。
数据下载。
软件信息。
在本节的内容中,将详细讲解本项目系统设置模块的实现过程。
6.6.1 主视图
系统设置主视图CSettingView.xib的UI界面效果如图6-15所示,分别列出了主题设置、当前城市、数据下载和软件信息共4个选项。
实现文件CSettingViewController.m的主要代码如下所示。
@implementation CSettingViewController
@synthesize settingTableView;
@synthesize cityNumLab;
@synthesize currentCityLab;
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *returnInfoBtn = [[UIBarButtonItem alloc] initWithTitle:@"反馈" style:UIBarButtonItemStylePlain
target:self action:@selector(SendEmail:)];
self.navigationItem.rightBarButtonItem = returnInfoBtn;// returnKeyBord
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(170, 16, 100, 20)];
label.font = [UIFont systemFontOfSize:13];
label.textColor = [UIColor darkGrayColor];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentRight;
self.cityNumLab = label;
[label release];
label = [[UILabel alloc] initWithFrame:CGRectMake(130, 16, 140, 20)];
label.font = [UIFont systemFontOfSize:13];
label.textColor = [UIColor darkGrayColor];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentRight;
self.currentCityLab = label;
[label release];
NSString *path = [[NSBundle mainBundle] pathForResource:@"URLDatabase" ofType:@"plist"];
if (path){
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
cityNum = [dict count];
}
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.settingTableView reloadData];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSInteger styleNum = [userDefault integerForKey:@"styleType"];
switch (styleNum) {
case 0:{
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
self.searchDisplayController.searchBar.barStyle = UIBarStyleDefault;
break;
}
case 1:{
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyle
BlackOpaque;
self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
self.searchDisplayController.searchBar.barStyle = UIBarStyleBlackOpaque;
break;
}
}
}
- (IBAction) SendEmail:(id)sender{
NSLog(@"--------sendEmail---");
MFMailComposeViewController *mailCompose = [[MFMailComposeViewController alloc] init];
if(mailCompose){
[mailCompose setMailComposeDelegate:self];
NSArray *toAddress = [NSArray arrayWithObject:@"haichao.xx@163.com"];
NSArray *ccAddress = [NSArray arrayWithObject:@"125379283@qq.com"];
[mailCompose setToRecipients:toAddress];
[mailCompose setCcRecipients:ccAddress];
[mailCompose setSubject:@"City_Bus"];
[self presentModalViewController:mailCompose animated:YES];
}
[mailCompose release];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWith Result:(MFMailComposeResult)result error:(NSError*)error{
// Notifies users about errors associated with the interface
switch (result){
case MFMailComposeResultCancelled:{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Send e-mail Cancel"
message:@""
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
break;
case MFMailComposeResultSaved:{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"E-mail have been saved"
message:@""
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
break;
case MFMailComposeResultSent:{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"E-mail has been sent"
message:@""
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
break;
case MFMailComposeResultFailed:{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"E-mail Fail to send"
message:@""
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
break;
default:{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"E-mail Not Sent"
message:@""
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
break;
}
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark -
#pragma mark Table view data source
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if (section == 0) {
return @"系统设置";
}
else if (section == 1) {
return @"数据设置";
}
else if (section == 2) {
return @"软件信息";
}
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 30;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section
if (section == 1){
return 2;
}
return 1;
}
// 自定义单元格的外观
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndex Path *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// 配置单元格
if (indexPath.section == 0){
cell.textLabel.text = @"主题设置";
}
else if(indexPath.section == 1){
if (indexPath.row == 0) {
currentCityLab.text = [[NSString alloc] initWithFormat:@"当前城市:%@", [CDataContainer Instance].currentCityName];
[cell.contentView addSubview:currentCityLab];
cell.textLabel.text = @"当前城市";
}
else if(indexPath.row == 1){
cityNumLab.text = [[NSString alloc] initWithFormat:@"城市数量:%d",cityNum];
[cell.contentView addSubview:cityNumLab];
cell.textLabel.text = @"数据下载";
}
}
else if(indexPath.section == 2){
cell.textLabel.text = @"软件信息";
}
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 用导航逻辑创造和推动另一个视图控制器
if(indexPath.section == 0 && indexPath.row == 0){
UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:@"选择主题"
delegate:self
cancelButtonTitle:@"Cancle"
destructiveButtonTitle:@"默认主题"
otherButtonTitles:@"黑色主题",nil];
actionSheet.actionSheetStyle = self.navigationController.navigationBar.barStyle;
[actionSheet showFromTabBar:self.tabBarController.tabBar];
[actionSheet release];
}
else if (indexPath.section == 1 && indexPath.row == 0) {
CBus_CurrentCityViewController *detailViewController = [[CBus_CurrentCity ViewController alloc] initWithNibName:@"CBus_CurrentCityView" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
else if (indexPath.section == 1 && indexPath.row == 1) {
CBus_CityDataViewController *detailViewController = [[CBus_CityDataView Controller alloc] initWithNibName:@"CBus_CityDataView" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
else if(indexPath.section == 2 && indexPath.row == 0){
CBus_InfoViewController *detailViewController = [[CBus_InfoViewController alloc] initWithNibName:@"CBus_InfoView" bundle:nil];
// ...
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@"------%d-------",buttonIndex);
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
switch (buttonIndex) {
case 0:{
[UIApplication sharedApplication].statusBarStyle = UIStatusBar StyleDefault;
self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
[userDefault setInteger:EDefaultType forKey:@"styleType"];
break;
}
case 1:{
[UIApplication sharedApplication].statusBarStyle = UIStatusBar StyleBlackOpaque;
self.navigationController.navigationBar.barStyle = UIBarStyle
BlackOpaque;
[userDefault setInteger:EBlackType forKey:@"styleType"];
break;
}
}
[userDefault synchronize];
}
- (void)dealloc {
[settingTableView release];
[cityNumLab release];
[currentCityLab release];
[super dealloc];
}
@end
执行效果如图6-16所示。
6.6.2 当前城市视图
系统当前城市视图CBus_CurrentCityView.xib的UI界面效果如图6-17所示,在此界面显示了系统可以查看哪一座城市的公交信息。
实现文件CBus_CurrentCityViewController.m的主要代码如下所示。
@implementation CBus_CurrentCityViewController
@synthesize lastIndexPath;
@synthesize selectCityName;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.title = [CDataContainer Instance].currentCityName;
self.navigationItem.prompt = @"点击设置当前城市:";
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
if ([self.selectCityName isEqualToString:[CDataContainer Instance].currentCity Name] || self.selectCityName == nil) {
return;
}
else {
[CDataContainer Instance].currentCityName = self.selectCityName;
[userDefault setObject:[CDataContainer Instance].currentCityName forKey:@ "currentCityName"];
[userDefault synchronize];
{
[[CDataContainer Instance] CloseDatabase];
[[CDataContainer Instance] clearData];
[CDataContainer releaseInstance];
[[CDataContainer Instance] viewDidLoad];
}
for (UINavigationController *controller in self.tabBarController.viewControllers) {
[controller popToRootViewControllerAnimated:NO];
}
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section
return [[CDataContainer Instance].downloadCitysArray count];
}
// Customize the appearance of table view cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
NSUInteger oldRow = [lastIndexPath row];
cell.textLabel.text = [[CDataContainer Instance].downloadCitysArray objectAtIndex: indexPath.row];
cell.imageView.image = [UIImage imageNamed:@"bus_city_select.png"];
cell.accessoryType = (row == oldRow && lastIndexPath != nil) ?
UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
// Configure the cell...
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditing Style)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRow Animation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int newRow = [indexPath row];
int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if (newRow != oldRow){
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *selectName = [[CDataContainer Instance].downloadCitysArray objectAtIndex: indexPath.row];
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUser DomainMask, YES);
NSString *currentCity = [[NSString alloc] initWithFormat:@"%@%@",selectName,@".db"];
NSString *writableDBPath = [[paths objectAtIndex:0] stringByAppendingPathComponent: currentCity];
NSLog(@"writableDBPath-----%@",writableDBPath);
success = [fileManager fileExistsAtPath:writableDBPath];
if (success){
self.selectCityName = selectName;
NSLog(@"-----数据库存在-----");
}
else {
NSLog(@"-----数据库不存在-----");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"警告"
message:@"所选择的城市数据库不存在"
delegate:self cancelButtonTitle:@"确定"otherButtonTitles:nil];
[alert show];
[alert release];
[[CDataContainer Instance].downloadCitysArray removeObject:selectName];
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
[userDefault setObject:[CDataContainer Instance].downloadCitysArray forKey: @"downloadCitys"];
[userDefault synchronize];
[self.tableView reloadData];
}
NSLog(@"currentCity-----%@-----",[CDataContainer Instance].currentCityName);
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
[lastIndexPath release];
[selectCityName release];
}
@end
执行效果如图6-18所示。
6.6.3 数据下载视图
数据下载视图CBus_CityDataView.xib的UI界面效果如图6-19所示,在此界面可以选择下载一座城市的公交信息数据。
实现文件CBus_CityDataViewController.m的主要代码如下所示。
@implementation CBus_CityDataViewController
@synthesize cityDataTableView;
@synthesize progressView;
@synthesize urlArray;
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.prompt = @"选择城市名称进行数据下载:";
progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressView StyleDefault];
progressView.frame = CGRectMake(100, 20, 200, 10);
progressView.progress = 0.0;
NSString *path = [[NSBundle mainBundle] pathForResource:@"URLDatabase" ofType:@"plist"];
if (path){
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
[CDataContainer Instance].allCityArray = [NSMutableArray arrayWithArray:[dict allKeys]];
if (urlArray == nil) {
urlArray = [[NSMutableArray alloc] init];
}
self.urlArray = [NSMutableArray arrayWithArray:[dict allValues]];
NSLog(@"urlArray-----%@",urlArray);
}
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.title = @"城市信息下载";
[[HttpRequest sharedRequest] setRequestDelegate:self];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[HttpRequest sharedRequest] setRequestDelegate:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Table view data source
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger) section{
return nil;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section
return [[CDataContainer Instance].allCityArray count];
}
// Customize the appearance of table view cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.selectionStyle = UITableViewCellSelectionStyleGray;
// Configure the cell
cell.textLabel.text = [[CDataContainer Instance].allCityArray objectAtIndex:index Path.row];
cell.imageView.image = [UIImage imageNamed:@"bus_download.png"];
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.cityDataTableView.userInteractionEnabled = NO;
downloadCityName = [NSString stringWithString:[[CDataContainer Instance].allCity Array objectAtIndex:indexPath.row]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUser DomainMask, YES);
NSString *tempPath = [[paths objectAtIndex:0]stringByAppendingPathComponent: [urlArray objectAtIndex:indexPath.row]];
progressView.hidden = NO;
progressView.progress = 0.0;
[[tableView cellForRowAtIndexPath:indexPath].contentView addSubview:progressView];
[[HttpRequest sharedRequest] sendDownloadDatabaseRequest:[urlArray objectAtIndex: indexPath.row] desPath:tempPath];
}
// 开始发送请求,通知外部程序
- (void)connectionStart:(HttpRequest *)request
{
NSLog(@"开始发送请求,通知外部程序");
}
// 连接错误,通知外部程序
- (void)connectionFailed:(HttpRequest *)request error:(NSError *)error
{
NSLog(@"连接错误,通知外部程序");
self.cityDataTableView.userInteractionEnabled = YES;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"连接错误"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
[alert release];
}
// 开始下载,通知外部程序
- (void)connectionDownloadStart:(HttpRequest *)request
{
NSLog(@"开始下载,通知外部程序");
}
// 下载结束,通知外部程序
- (void)connectionDownloadFinished:(HttpRequest *)request
{
NSLog(@"下载结束,通知外部程序");
self.progressView.hidden = YES;
self.cityDataTableView.userInteractionEnabled = YES;
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
BOOL isNotAlready = YES;
for(NSString *name in [CDataContainer Instance].downloadCitysArray){
if ([name isEqualToString:downloadCityName]) {
isNotAlready = NO;
}
}
if (isNotAlready) {
[[CDataContainer Instance].downloadCitysArray addObject:downloadCityName];
[userDefault setObject:[CDataContainer Instance].downloadCitysArray forKey:@"downloadCitys"];
[userDefault synchronize];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"下载完成"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
[alert release];
}
// 更新下载进度,通知外部程序
- (void)connectionDownloadUpdateProcess:(HttpRequest *)request process:(CGFloat)process
{
NSLog(@"Process = %f", process);
progressView.progress = process;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
[cityDataTableView release];
[progressView release];
[urlArray release];
}
@end
执行效果如图6-20所示。