本文原創,轉載請注明出處!
哦吼吼,又研究了幾天,把FMDB這個封裝好的數據庫搞定了,寫了個簡單的例子,基於FMDB的添刪改查操作,界面很一般了,代碼可能比較亂,希望不要傷了各位的眼睛。依舊是純代碼實現的,沒有用到任何IB,其中添加刪除更改的操作都非常簡單,不需要做太多操作,只需要用到FMDB封裝好的executeUpdate方法就行了。搜索功能用到了UISearchDisplayController這個控件,因為以前沒有用過,研究了一天才搞定。下面對界面做簡單的說明:
整個界面使用一個UITabBarController實現的,一共有三個TabBarItem,第一個是通訊錄,我重寫了cell,在每一行可以顯示姓名,電話和ID。我要說明一下ID,ID最好每個人的都不要寫成一樣的,如果兩個人的姓名一樣,ID也一樣的話,在刪除一個人的時候會把兩個人的信息都刪掉。右上角是更新button,先選擇某一項,再點那個button就可以進入更新界面。下面來看更新界面:
進入更新界面,可以更新姓名和電話,ID是不可更改的,為什么呢,因為在操作數據庫的時候必須要有一個主鍵(PRIMARY KEY),作為區分每條數據的標識。注意右上角是save。下面來看添加信息的頁面,也就是第二個TabBarItem:
可以添加姓名,電話和ID,注意ID不要和其他的相同!再來看第三個TabBarItem,搜索功能,這是我新學的一個知識,用UISearchDisplayController和UISearchBar來實現的搜索,因為用這兩個可以達到最好的圖像效果
搜索出來的數據點擊某一行可以進入詳情:
這個頁面就簡單了,沒什么可說的了,一目了然。
下面為大家呈上代碼,首先要在AppDelegate.m文件里做修改,要放入一個UITabBar
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease]; //因為有三個tabBarItem,我把系統默認的viewController放在了第一個,然后再新建兩個繼承自UIViewController的類AddUserInfo和SearchInfo UINavigationController *viewController = [[UINavigationController alloc]initWithRootViewController:self.viewController]; viewController.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemContacts tag:101]; //將viewController初始化為第一個tabBarItem AddUserInfo *adduserViewController = [[AddUserInfo alloc]init]; adduserViewController.title = @"添加用戶信息"; adduserViewController.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemTopRated tag:102]; //將adduserViewController初始化為第二個tabBarItem SearchInfo *searchViewController = [[SearchInfo alloc]init]; searchViewController.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemSearch tag:103]; searchViewController.title = @"搜索信息"; //將searchViewController初始化為第三個tabBarItem,現在已經准備了UITabBarController上的三個tabBarItem了,但是每一個tabBarItem都需要放到UINavigationController上來控制視圖,在初始化兩個UINavigationController,還有一個在上面。 UINavigationController *nav1= [[UINavigationController alloc]initWithRootViewController:adduserViewController]; UINavigationController *nav2 = [[UINavigationController alloc]initWithRootViewController:searchViewController]; NSArray *ViewControllerArray = [[NSArray alloc]initWithObjects:viewController,nav1,nav2, nil]; // 將三個UINavigationController添加到一個數組里,tabBarItem已經搞定了,但是主要的UITabBarController我們現在來初始化。 UITabBarController *tabBarController = [[UITabBarController alloc]init]; //注意這里的用法,tabBarController.viewControllers是tabBarController的一個數組類型的屬性,它存放的是UINavigationController tabBarController.viewControllers = ViewControllerArray; tabBarController.selectedIndex = 0;//初始顯示第一個tabBarItem tabBarController.delegate = self;//別忘了設置代理,在頭文件里要加上 <UIApplicationDelegate,UITabBarControllerDelegate>這兩個 self.window.rootViewController = tabBarController; [self.window makeKeyAndVisible]; [nav1 release]; [nav2 release]; [tabBarController release]; [ViewControllerArray release]; [searchViewController release]; [adduserViewController release]; [viewController release]; return YES; }
接下來去下載FMDB工程項目https://github.com/ccgus/fmdb.git
下載下來的是一個demo,大家可以把src文件夾拖出來再改名為FMDB,拖進自己的項目及就行了
在項目里添加libsqlite3.dylib,SenTestingKit.framework兩個庫,還有頭文件#import "FMDatabase.h"和
#import "FMDatabaseQueue.h"
來看看通訊錄頁面ViewController.h
#import <UIKit/UIKit.h> #import "FMDatabase.h" #import "FMDatabaseQueue.h" @class dataFromDataBase; @interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource> { } @property (nonatomic, retain) NSString * dbPath; @property (nonatomic, retain) NSMutableArray *nameArray; @property (nonatomic, retain) NSMutableArray *phoneArray; @property (nonatomic, retain) NSMutableArray *IDArray; @property (nonatomic, retain) UITableView *table; - (void)createTable; @end @interface dataFromDataBase : NSObject {//新建一個類,專門用於保存數據 @private NSString *nameFromClass; NSString *phoneFromClass; NSString *IDFromClass; NSMutableArray *nameArrayFromClass; } +(dataFromDataBase*)shareFromDataBase;//神奇的單例 @property(retain,nonatomic) NSString *nameFromClass; @property(retain,nonatomic)NSString *phoneFromClass; @property(retain,nonatomic)NSString *IDFromClass; @property(retain,nonatomic)NSMutableArray *nameArrayFromClass; @end
ViewController.m
// // ViewController.m // tabbartest // // Created by changjian on 12-12-8. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import "ViewController.h" #import "AddUserInfo.h" @implementation ViewController @synthesize dbPath; @synthesize nameArray,phoneArray,IDArray; @synthesize table; - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; self.title = @"通訊錄"; UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 369) style:UITableViewStylePlain]; tableView.delegate = self; tableView.dataSource = self; self.table = tableView; [self.view addSubview:tableView]; UIBarButtonItem *refreshBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(modifyDatabase)]; self.navigationItem.rightBarButtonItem = refreshBtn; [refreshBtn release]; } #pragma mark -tableview- - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // NSString *CustomIdentifier = [NSString stringWithFormat:@"cell%d",indexPath.row]; static NSString *CustomIdentifier = @"cell"; // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomIdentifier]; UITableViewCell *cell = nil; if (cell == nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CustomIdentifier]; } // while ([cell.contentView.subviews lastObject] != nil){ [(UIView*)[cell.contentView.subviews lastObject]removeFromSuperview];//當再次刷新的時候會自動添加新的cell,出現疊加情況,用這種方法可以去掉上一次添加的cell.contentView.subviews if (indexPath.row == 0)//這里注意,因為第一行不顯示數據,所以做個判斷 cell.selectionStyle = UITableViewCellSelectionStyleNone; if (indexPath.row > 0) {//從第二行開始顯示數據 // cell.textLabel.text = [dataArray objectAtIndex:(indexPath.row - 1)];//注意這里是從indexPath.row - 1行開始 UILabel *nameLabel = [[UILabel alloc]initWithFrame:CGRectMake(0+40, 10, 70, 30)]; UILabel *phoneLabel = [[UILabel alloc]initWithFrame:CGRectMake(90+40, 10, 70, 30)]; UILabel *IDLabel = [[UILabel alloc]initWithFrame:CGRectMake(180+40, 10, 70, 30)]; nameLabel.text = [self.nameArray objectAtIndex:(indexPath.row-1)]; IDLabel.text = [self.IDArray objectAtIndex:(indexPath.row-1)]; phoneLabel.text = [self.phoneArray objectAtIndex:(indexPath.row-1)]; [cell.contentView addSubview:nameLabel]; [cell.contentView addSubview:IDLabel]; [cell.contentView addSubview:phoneLabel]; [nameLabel release]; [IDLabel release]; [phoneLabel release]; } else { for (int i = 0; i < 3; i ++) { UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(90 * i + 40, 10, 70 , 30)]; NSArray *array = [NSArray arrayWithObjects:@"姓名",@"電話",@"ID", nil]; label.text = [array objectAtIndex:i]; label.backgroundColor = [UIColor clearColor]; [cell.contentView addSubview:label]; [label release]; label = nil; } } // } return cell; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [nameArray count] + 1;//注意這里,因為第一行不顯示數據,返回要加一行 } - (NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) { return nil;//讓第一行不能點擊 } else return indexPath; } - (void)createTable//創建數據庫中表的方法,利用封裝好的庫很簡單 { NSFileManager *fileManager = [NSFileManager defaultManager]; if (![fileManager fileExistsAtPath:self.dbPath]) { NSLog(@"表不存在,創建表"); FMDatabase *db =[FMDatabase databaseWithPath:self.dbPath]; if ([db open]) { NSString *sql = @"CREATE TABLE 'USER'('id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 'name' VARCHAR(20),'phone' VARCHAR(20),'idcode' VARCHAR(30)) ";//sql語句 BOOL success = [db executeUpdate:sql]; if (!success) { NSLog(@"error when create table "); }else{ NSLog(@"create table succeed"); } [db close]; }else{ NSLog(@"database open error"); } } } - (void)getAllDatabase//從數據庫中獲得所有數據 { FMDatabase *db = [FMDatabase databaseWithPath:self.dbPath]; if ([db open]) { NSString *sql = @"SELECT * FROM USER"; FMResultSet *rs = [db executeQuery:sql]; while ([rs next]) { NSString *name = [rs stringForColumn:@"name"]; NSString *phone = [rs stringForColumn:@"phone"]; NSString *ID = [rs stringForColumn:@"idcode"]; [self.nameArray addObject:name]; [self.phoneArray addObject:phone]; [self.IDArray addObject:ID]; } [[dataFromDataBase shareFromDataBase].nameArrayFromClass arrayByAddingObjectsFromArray:self.nameArray]; NSLog(@"self.nameArray==%@",self.nameArray); [db close]; [table reloadData]; } } - (void)modifyDatabase//選中相應的行,進入更新界面,注意這里沒有對數據庫進行操作 { NSIndexPath *indexPath = [self.table indexPathForSelectedRow]; if (indexPath == nil) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"請選擇要更新的項" delegate:self cancelButtonTitle:@"好" otherButtonTitles:nil]; [alert show]; [alert release]; return; } else{ AddUserInfo *modify = [[AddUserInfo alloc]init]; modify.operateType = 1; //下面的方法是將選中的行的數據存進單例,再傳到另一個類里面 [dataFromDataBase shareFromDataBase].nameFromClass = [self.nameArray objectAtIndex:(indexPath.row-1)]; [dataFromDataBase shareFromDataBase].IDFromClass = [self.IDArray objectAtIndex:(indexPath.row-1)]; [dataFromDataBase shareFromDataBase].phoneFromClass = [self.phoneArray objectAtIndex:(indexPath.row-1)]; NSLog(@"datafromdatabase.nameFromClass==%@",[dataFromDataBase shareFromDataBase].nameFromClass); [self.navigationController pushViewController:modify animated:YES];//跳轉到修改頁面 [modify release]; } } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [nameArray release]; [phoneArray release]; [IDArray release]; [super dealloc]; } - (void)viewWillAppear:(BOOL)animated { NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; NSString *path = [document stringByAppendingPathComponent:@"USER.sqlite"]; self.dbPath = path; //注意以上三句話是獲取數據庫路徑必不可少的,在viewDidload之前就已經准備好了 nameArray = [[NSMutableArray alloc]init]; phoneArray = [[NSMutableArray alloc]init]; IDArray = [[NSMutableArray alloc]init]; [self createTable]; [self getAllDatabase]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); } @end @implementation dataFromDataBase//這個類專門用來保存數據 @synthesize nameFromClass,phoneFromClass,IDFromClass; @synthesize nameArrayFromClass; static dataFromDataBase *sharedInstance = nil; +(dataFromDataBase*)shareFromDataBase//偉大的單例, { if (sharedInstance == nil) { sharedInstance = [[dataFromDataBase alloc]init]; } return sharedInstance; } - (id)init { self = [super init]; if (self) { nameFromClass = @""; phoneFromClass = @""; IDFromClass = @""; nameArrayFromClass = [[NSMutableArray alloc]initWithCapacity:0]; } return self; } - (void)dealloc { if (nameFromClass!= nil){ [nameFromClass release]; } if (phoneFromClass!=nil){ [phoneFromClass release]; } if (IDFromClass != nil){ [IDFromClass release]; } if (nameArrayFromClass != nil) { [nameArrayFromClass release]; } [super dealloc]; } @end
下面是AddUserInfo.h文件
#import <UIKit/UIKit.h> #import "ViewController.h" @interface AddUserInfo : UIViewController<UITextFieldDelegate,UIAlertViewDelegate> { int operateType;//保存操作類型,0是添加,1是修改 } - (void)createTable; @property (retain,nonatomic)NSMutableArray *textFieldArray; @property (retain,nonatomic)NSString *dbPath; @property (retain,nonatomic)UITextField *nameTextField; @property (retain,nonatomic)UITextField *phoneTextField; @property (retain,nonatomic)UITextField *IDTextField; @property (nonatomic,assign)int operateType; @end
AddUserInfo.m文件
// // AddUserInfo.m // tabbartest // // Created by changjian on 12-12-8. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import "AddUserInfo.h" #import "FMDatabase.h" #import "FMDatabaseQueue.h" #import "UserDetailInfo.h" @implementation AddUserInfo @synthesize textFieldArray; @synthesize dbPath; @synthesize nameTextField; @synthesize phoneTextField; @synthesize IDTextField; @synthesize operateType; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { textFieldArray = [[NSMutableArray alloc]init]; } return self; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *path = [doc stringByAppendingPathComponent:@"user.sqlite"]; NSLog(@"path===%@",path); self.dbPath = path; NSArray *array = [NSArray arrayWithObjects:@"姓名",@"電話",@"ID", nil]; for (int i = 0; i < 3 ; i++) { UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake( 70,i * 40 + 34, 100, 30)]; label.text = [array objectAtIndex:i]; [self.view addSubview:label]; } nameTextField = [[UITextField alloc]initWithFrame:CGRectMake(150, 38, 100, 30)]; nameTextField.borderStyle = UITextBorderStyleRoundedRect; nameTextField.placeholder = @"請輸入姓名"; nameTextField.delegate = self; [self.view addSubview:nameTextField]; phoneTextField = [[UITextField alloc]initWithFrame:CGRectMake(150, 78, 100, 30)]; phoneTextField.borderStyle = UITextBorderStyleRoundedRect; phoneTextField.placeholder = @"請輸入電話"; phoneTextField.delegate = self; [self.view addSubview:phoneTextField]; IDTextField = [[UITextField alloc]initWithFrame:CGRectMake(150, 118, 100, 30)]; IDTextField.borderStyle = UITextBorderStyleRoundedRect; IDTextField.placeholder = @"請輸入ID"; IDTextField.delegate = self; [self.view addSubview:IDTextField]; if (operateType == 1) {//operateType == 1時為修改 nameTextField.text = [dataFromDataBase shareFromDataBase].nameFromClass; IDTextField.text = [dataFromDataBase shareFromDataBase].IDFromClass; phoneTextField.text = [dataFromDataBase shareFromDataBase].phoneFromClass; IDTextField.enabled = NO; NSLog(@"datafromdatabase.nameFromClass=%@",[dataFromDataBase shareFromDataBase].nameFromClass); } NSLog(@"operateType==%d",operateType); if (operateType == 0){ UIBarButtonItem *addBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewUserInfo)]; self.navigationItem.rightBarButtonItem = addBtn; } if(operateType == 1){//這里是后來添加的,其實可以放到上面 UIBarButtonItem *addBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(addNewUserInfo)]; self.navigationItem.rightBarButtonItem = addBtn; } // Do any additional setup after loading the view from its nib. } - (void)addNewUserInfo//添加用戶信息的方法,用FMDB封裝好的方法 { FMDatabase *db = [[FMDatabase alloc]initWithPath:self.dbPath]; NSString *mes = nil; if ([db open]) { if (nameTextField.text.length == 0||phoneTextField.text.length == 0||IDTextField.text.length == 0){ mes = @"請完成填寫信息"; }else{ NSLog(@"姓名==%@,電話==%@,ID==%@",nameTextField.text,phoneTextField.text,IDTextField.text); NSString *sql= nil; if (operateType == 0){//執行插入操作 sql = @"INSERT INTO USER (name,phone,idcode) VALUES (?,?,?) "; }else if(operateType == 1)//執行更新操作 { sql = @"UPDATE USER SET name = ? , phone = ? where idcode = ?"; NSLog(@"有沒有執行?"); } BOOL res = [db executeUpdate:sql,nameTextField.text,phoneTextField.text,IDTextField.text]; if (!res) { NSLog(@"error to insert data"); mes = @"數據插入錯誤"; }else{ NSLog(@"insert succeed"); mes = @"數據插入成功"; } } }else{ NSLog(@"數據庫打開失敗") ; } UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:mes delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil]; [alert setTag:101]; alert.delegate = self; [alert show]; [alert release]; [db close]; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (alertView.tag == 101 && buttonIndex == 0) { if (operateType == 0)//如果是添加就留在該頁,如果是修改就跳回上一頁 { [nameTextField resignFirstResponder]; [phoneTextField resignFirstResponder]; [IDTextField resignFirstResponder]; nameTextField.text = @""; phoneTextField.text = @""; IDTextField.text = @""; }else{ [self.navigationController popViewControllerAnimated:YES]; } } } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [nameTextField resignFirstResponder]; [phoneTextField resignFirstResponder]; [IDTextField resignFirstResponder]; }//讓鍵盤隱藏 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:YES]; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [nameTextField release]; [phoneTextField release]; [IDTextField release]; [textFieldArray release]; [super dealloc]; } -(void)viewWillDisappear:(BOOL)animated//頁面將要消失的時候執行,將UITextField清空 { [super viewWillDisappear:YES]; nameTextField.text = nil; phoneTextField.text = nil; IDTextField.text = nil; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end
下面是SearchInfo.h文件,一定要注意這個類是繼承UITableViewController,不是UIViewController!!!
// // SearchInfo.h // tabbartest // // Created by changjian on 12-12-8. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import <UIKit/UIKit.h> @interface SearchInfo : UITableViewController<UISearchDisplayDelegate,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate> { UISearchDisplayController *searchController; NSString *namestr; NSString *phonestr; NSString *IDstr; } @property (retain,nonatomic)NSString *dbpath; @property (retain,nonatomic)NSMutableArray *searchResults;//用於保存搜索出姓名的結果 @property (retain,nonatomic)NSMutableArray *searchPhoneResults;//用來保存搜索的電話信息 @property (retain,nonatomic)NSMutableArray *searchIDResult;//用來保存搜索的ID信息 @property (retain,nonatomic)NSMutableArray *nameArray;//保存搜索之前的姓名信息 @property (retain,nonatomic)NSMutableArray *phoneArray;//保存搜索之前的電話信息 @property (retain,nonatomic)NSMutableArray *IDArray;//保存搜索之前的ID信息 @property (nonatomic,assign)BOOL searchWasActive; @property (nonatomic,assign)NSString *savedSearchTerm;//這個好像沒用了 @property (nonatomic,retain)NSString *namestr; @property (nonatomic,retain)NSString*phonestr; @property (nonatomic,retain)NSString*IDstr; - (void)getAllDatabase; @end
SearchInfo.m文件
// // SearchInfo.m // tabbartest // // Created by changjian on 12-12-8. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import "SearchInfo.h" #import "FMDatabase.h" #import "ViewController.h" #import "UserDetailInfo.h" @implementation SearchInfo @synthesize dbpath; @synthesize searchResults,searchPhoneResults,searchIDResult; @synthesize nameArray,phoneArray,IDArray; @synthesize searchWasActive; @synthesize savedSearchTerm; @synthesize namestr,phonestr,IDstr; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; //搜索比較復雜,既要初始化UISearchBar,又要初始化UISearchDisplayController,然后還要寫UITableViewDelegate里的-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath和-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section方法,還要設置一大堆代理,慢慢往下看 UISearchBar *search = [[[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width -50, 44)]autorelease]; search.placeholder = @"請輸入姓名"; search.autocorrectionType = UITextAutocorrectionTypeNo;//不自動糾錯,貌似沒啥用 search.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;//所有字母大寫 ,也沒啥用 search.showsScopeBar = YES; search.delegate = self;//UISearchBar設置代理 search.keyboardType = UIKeyboardTypeNamePhonePad; self.tableView.tableHeaderView = search; self.tableView.dataSource = self; searchController = [[UISearchDisplayController alloc]initWithSearchBar:search contentsController:self]; searchController.active = NO; searchController.delegate = self;//UISearchDisplayController設置代理 searchController.searchResultsDelegate=self;//還是代理 searchController.searchResultsDataSource = self;//有完沒完 [search release]; NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; NSString *path = [document stringByAppendingPathComponent:@"user.sqlite"]; NSLog(@"path==%@",path); self.dbpath = path; self.tableView.delegate = self;//tableView的代理,為什么這么寫,因為這個類是繼承UITableView的,要注意!不是繼承UIViewController的! self.tableView.dataSource = self; nameArray = [[NSMutableArray alloc]initWithCapacity:0]; phoneArray = [[NSMutableArray alloc]initWithCapacity:0]; IDArray= [[NSMutableArray alloc]initWithCapacity:0]; [self getAllDatabase]; [self.tableView reloadData]; // Do any additional setup after loading the view from its nib. } - (void)viewWillAppear:(BOOL)animated { self.searchWasActive = [self.searchDisplayController isActive]; if (self.searchDisplayController.searchBar != 0) { self.searchDisplayController.searchBar.text = nil; [self.searchDisplayController.searchBar resignFirstResponder]; [self.searchDisplayController setActive:NO];//在進入搜索頁面之前將其設置為不活動,大家可以試試改成活動看看是什么樣 } } - (void)getAllDatabase//要重新獲取數據庫信息,因為執行完刪除之后數據庫變了 { FMDatabase *db = [FMDatabase databaseWithPath:self.dbpath]; if ([db open]) { NSString *sql = @"SELECT * FROM USER"; FMResultSet *rs = [db executeQuery:sql]; while ([rs next]) { NSString *name = [rs stringForColumn:@"name"]; NSString *phone = [rs stringForColumn:@"phone"]; NSString *ID = [rs stringForColumn:@"idcode"]; [self.nameArray addObject:name]; [self.phoneArray addObject:phone]; [self.IDArray addObject:ID]; } self.searchResults = [[NSMutableArray alloc]initWithArray:nameArray copyItems:YES]; self.searchPhoneResults = [[NSMutableArray alloc]initWithArray:phoneArray copyItems:YES]; self.searchIDResult = [[NSMutableArray alloc]initWithArray:IDArray copyItems:YES]; NSLog(@"search from nameArray==%@",self.nameArray); [db close]; } } #pragma mark -tableview- -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // self.tableView = tableView; static NSString *cellIdentifier = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]) { cell.textLabel.text = [searchResults objectAtIndex:indexPath.row]; // cell.detailTextLabel.text = [NSString stringWithFormat:@"電話:%@",[searchResults objectAtIndex:indexPath.row]];//不知道為什么不顯示cell.detailTextLabel.text ,有人知道的話告訴我一下 }else{ cell.textLabel.text = [self.nameArray objectAtIndex:indexPath.row]; } return cell; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSInteger row = 0; if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]) {//記住這個格式,如果當前的table就是用於顯示所搜信息的table的話。因為UISearchDisplayController這貨自帶一個table row = [self.searchResults count]; }else{ [self.nameArray count]; } return row; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UserDetailInfo *detailInfo = [[UserDetailInfo alloc]init]; detailInfo.nameStr = [self.searchResults objectAtIndex:indexPath.row]; detailInfo.phoneStr = [self.searchPhoneResults objectAtIndex:indexPath.row]; detailInfo.IDsStr = [self.searchIDResult objectAtIndex:indexPath.row]; NSLog(@"self.namestr==%@",self.namestr); NSArray *array = [self.navigationController viewControllers];//先獲取視圖控制器數組 UINavigationController *nav = [array objectAtIndex:[array count] - 1];//獲取當前的導航試圖控制器 [nav.navigationController pushViewController:detailInfo animated:YES];//跳轉到刪除頁面 [detailInfo release]; } #pragma mark -UISearchControllerDisplay-//設置搜索范圍 //下面注意了,下面的方法是實現搜索功能的,后面兩個長得很像的方法是UISearchControllerDisplay代理里的方法,我也搞不懂是干什么用的,他們的格式很固定,大家記住就行了。 - (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { [self searchBarSearchButtonClicked:self.searchDisplayController.searchBar]; } - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar//從數據庫搜索 { FMDatabase *db = [FMDatabase databaseWithPath:self.dbpath]; if ([db open]) { [searchResults removeAllObjects]; [searchPhoneResults removeAllObjects]; [searchIDResult removeAllObjects]; NSString *sql = @"SELECT * FROM USER WHERE name like ?"; FMResultSet *rs = [db executeQuery:sql,searchBar.text]; while ([rs next]) { self.namestr = [rs stringForColumn:@"name"]; self.phonestr = [rs stringForColumn:@"phone"]; self.IDstr = [rs stringForColumn:@"idcode"]; [self.searchResults addObject:namestr]; [self.searchPhoneResults addObject:phonestr]; [self.searchIDResult addObject:IDstr]; } NSLog(@"searchResults == %@",searchResults); NSLog(@"searchPhoneResults==%@",searchPhoneResults); NSLog(@"searchIDResult==%@",searchIDResult); NSLog(@"search===%@",searchBar.text); } [db close]; } #pragma mark - #pragma mark UISearchDisplayController Delegate Methods設置代理方法 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { [self filterContentForSearchText:searchString scope: [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]]; // Return YES to cause the search result table view to be reloaded. return YES; } - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { [self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope: [[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]]; // Return YES to cause the search result table view to be reloaded. return YES; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } - (void)dealloc { [nameArray release]; [phoneArray release]; [IDArray release]; [searchController release]; [searchResults release]; [searchPhoneResults release]; [searchIDResult release]; [super dealloc]; } @end
最難的部分完了,接下來就簡單多了!
最后是刪除信息界面UserDetailInfo.h
@interface UserDetailInfo : UIViewController<UIAlertViewDelegate> { } @property(retain,nonatomic)NSString *dbpath; @property(retain,nonatomic)NSString *nameStr; @property(retain,nonatomic)NSString *phoneStr; @property(retain,nonatomic)NSString *IDsStr; @end
UserDetailInfo.m
// // UserDetailInfo.m // tabbartest // // Created by changjian on 12-12-10. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. // #import "UserDetailInfo.h" #import "FMDatabase.h" @implementation UserDetailInfo @synthesize dbpath; @synthesize nameStr,phoneStr,IDsStr; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; self.title = @"詳細信息"; NSArray *array = [NSArray arrayWithObjects:@"姓名:",@"電話:",@"ID:", nil]; NSArray *array2 = [NSArray arrayWithObjects:self.nameStr,self.phoneStr,self.IDsStr, nil]; for (int i = 0; i < 3 ; i++) { UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake( 70,i * 40 + 34, 100, 30)]; label.text = [array objectAtIndex:i]; [self.view addSubview:label]; UILabel *label2 = [[UILabel alloc]initWithFrame:CGRectMake(140, i * 40 +35, 100, 30)]; label2.text = [array2 objectAtIndex:i]; [self.view addSubview:label2]; [label release]; [label2 release]; } NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; NSString *path = [document stringByAppendingPathComponent:@"USER.sqlite"]; self.dbpath = path; UIBarButtonItem *deleteButton = [[UIBarButtonItem alloc]initWithTitle:@"刪除" style:UIBarButtonItemStyleDone target:self action:@selector(deleteFromDatabase)]; self.navigationItem.rightBarButtonItem = deleteButton; } - (void)deleteFromDatabase//從數據庫刪除信息 { FMDatabase *db = [FMDatabase databaseWithPath:self.dbpath]; NSString *mes = nil; if ([db open]) { NSString *sql = @"DELETE FROM USER WHERE name = ? and phone = ? and idcode = ?"; if (self.nameStr.length != 0&&self.phoneStr.length != 0&&self.IDsStr.length !=0){ BOOL rs = [db executeUpdate:sql,self.nameStr,self.phoneStr,self.IDsStr]; //后面跟的三個參數就是sql語句里的三個問號對應 if (rs) { mes = @"刪除成功"; }else{ mes = @"刪除失敗"; } } } UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:mes delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil, nil]; alert.delegate = self;//別忘了代理 [alert show]; [alert release]; [db close]; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if ( buttonIndex == 0) { [self.navigationController popViewControllerAnimated:YES]; NSLog(@"點擊了刪除成功"); } } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:YES]; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end
完全的代碼流,把代碼復制過去就直接能用,不過建議大家在復制之前一定要搞清楚寫法,最好自己再寫一遍,不然復制了下次還是不會。有什么問題記得給我留言。