本篇文章通过学习sqlite3来实现一个简单的英文生词本,首先把效果图贴上了:
现在开始程序的步骤:
一,新建一个simple view工程,记住要勾选storyboard和arc
二,在生成的main.storyboard中画界面:
1.主界面如图所示(三个textField和两个button):
2,绘制查询结果页面:
1),首先在storyboard中拖进去一个TableViewController视图
2),再拖进去一个Navigation Bar,放在controller的最上面
3),再给导航栏的左侧拖进去一个Bar Button Item,命名为“返回”
4),再在PrototypeCells下面的空白处拖入两个UILabel,给两个UILabel的属性tag分别设置为1和2
完了选中Table View Cell视图,然后将属性Identifier设置为cell,如下图所示:
三,再工程自动生成的ViewController的头文件中添加属性和事件方法:
@property (strong, nonatomic) IBOutlet UITextField *wordField;
@property (strong, nonatomic) IBOutlet UITextField *detailField;
@property (strong, nonatomic) IBOutlet UITextField *keyField;
- (IBAction)finishEdit:(id)sender;
- (IBAction)addWord:(id)sender;
四,再回到storyboard中,这次我们需要给这些文本框和按钮连线来初始化:
1.首先明确定义第三步的三个文本框分别对应主视图中的从上到下得文本框,因此,连线的时候需要给三个文本框都设置Did End On Exit事件,赋值是finishEdit
2.然后在Referencing Outlets下面拖动连线,初始化三个文本框,如下图所示(其余两个文本框同理):
3.接着给“添加生词”和“查找”两个按钮连线,“添加生词”的事件为Touch Up Inside,事件方法为addWord,“查找”按钮需要连接action,连接新建的那个结果视图,模式选择为modal,如下图所示:
五,新建一个FKResultViewController类,不需要带storyboard,实现UITableViewController
六,再FKResultViewController得头文件中设置一个属性:
@property (nonatomic , copy) NSArray* wordArray;
七,回到storyboard,修改前面新添加的表视图的父类为FKResultViewController,如下图所示:
再给这个视图的“返回”按钮连线,如下图所示:
六,新建一个FKWord实体类,代码如下:
@interface FKWord : NSObject
@property (nonatomic, assign) NSInteger word_id;
@property (nonatomic, copy) NSString* word;
@property (nonatomic, copy) NSString* detail;
-(id) initWithId:(NSInteger)word_id word:(NSString*)word
detail:(NSString*)detail;
@end
@implementation FKWord
-(id) initWithId:(NSInteger)word_id word:(NSString*)word
detail:(NSString*)detail
{
self = [super init];
if (self) {
_word_id = word_id;
_word = word;
_detail = detail;
}
return self;
}
@end
七,实现
FKResultViewController.m类:#import "FKResultViewController.h"
#import "FKWord.h"
@implementation FKResultViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.wordArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
CellIdentifier forIndexPath:indexPath];
FKWord* wordObj = [self.wordArray objectAtIndex:indexPath.row];
UILabel* wordLabel = (UILabel*)[cell viewWithTag:1];
UILabel* detailLabel = (UILabel*)[cell viewWithTag:2];
wordLabel.text = wordObj.word;
detailLabel.text = wordObj.detail;
return cell;
}
@end
八,实现主视图的ViewController类:
#import <sqlite3.h>
#import "FKViewController.h"
#import "FKResultViewController.h"
#import "FKWord.h"
@implementation FKViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)finishEdit:(id)sender {
// 让该文本框放弃作为第一响应者
[sender resignFirstResponder];
}
- (IBAction)addWord:(id)sender
{
NSString* word = self.wordField.text;
NSString* detail = self.detailField.text;
// 只有当self.wordField、self.detailField两个控件内有内容时才执行插入
if(word != nil && word.length > 0
&& detail != nil && detail.length > 0)
{
sqlite3* database;
// 新建和打开数据库,database变量保存了打开的数据库的指针
sqlite3_open([[self dbPath] UTF8String], &database);
// 定义错误字符串
char * errMsg;
// 定义执行建表的SQL语句
const char * createSQL = "create table if not exists word_inf \
(_id integer primary key autoincrement,\
word,\
detail)";
// 执行建表语句
int result = sqlite3_exec(database, createSQL, NULL, NULL, &errMsg);
if (result == SQLITE_OK)
{
const char * insertSQL = "insert into word_inf values(null, ? , ?)";
sqlite3_stmt * stmt;
// 预编译SQL语句,stmt变量保存了预编译结果的指针
int insertResult = sqlite3_prepare_v2(database
, insertSQL, -1, &stmt, nil);
// 如果预编译成功
if (insertResult == SQLITE_OK)
{
// 为第一个?占位符绑定参数
sqlite3_bind_text(stmt, 1,
[word UTF8String], -1, NULL);
// 为第二个?占位符绑定参数
sqlite3_bind_text(stmt, 2,
[detail UTF8String], -1, NULL);
// 执行SQL语句
sqlite3_step(stmt);
// 将wordField、detailField控件的内容清空
self.wordField.text = @"";
self.detailField.text = @"";
}
sqlite3_finalize(stmt);
}
// 关闭数据库
sqlite3_close(database);
}
}
// 定义一个方法,获取数据库文件的保存路径。
- (NSString*) dbPath
{
// 获取应用的Documents路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [NSString stringWithFormat:@"%@/myWords.db"
, documentsDirectory];
}
// 当应用从该视图控制器过渡到下一个视图控制器时自动执行该方法
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString* key = self.keyField.text;
// 只有当self.keyField控件内有内容时才执行查询
if(key != nil && key.length > 0)
{
sqlite3* database;
// 新建或打开数据库,database变量保存了打开的数据库的指针
sqlite3_open([[self dbPath] UTF8String], &database);
const char * selectSQL = "select * from word_inf where word like ?";
sqlite3_stmt * stmt;
// 预编译SQL语句,stmt变量保存了预编译结果的指针
int queryResult = sqlite3_prepare_v2(database
, selectSQL, -1, &stmt, nil);
NSMutableArray* result = [[NSMutableArray alloc] init];
// 如果预编译成功
if(queryResult == SQLITE_OK)
{
// 为第一个?占位符绑定参数
sqlite3_bind_text(stmt, 1, [[NSString stringWithFormat:@"%%%@%%"
, key] UTF8String], -1, NULL);
// 采用循环多次执行sqlite3_step()函数,并从中取出查询结果
while (sqlite3_step(stmt) == SQLITE_ROW)
{
// 分别获取当前行的不同列的查询数据
int word_id = sqlite3_column_int(stmt , 0);
char* word = (char*)sqlite3_column_text(stmt , 1);
char* detail = (char*)sqlite3_column_text(stmt , 2);
// 将当前行的数据封装成FKWord对象
FKWord * wordObj = [[FKWord alloc] initWithId:word_id
word:[NSString stringWithUTF8String:word]
detail:[NSString stringWithUTF8String:detail]];
[result addObject:wordObj];
}
}
// 关闭数据库
sqlite3_close(database);
FKResultViewController* resultViewController =
(FKResultViewController*)segue.destinationViewController;
// 将查询结果传给FKResultViewController对象显示
resultViewController.wordArray = result;
}
}
@end