本节书摘来自异步社区《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所示。