UI:数据库练习、滤镜效果

相机处理滤镜效果

滤镜主要使用在相机的美颜。

#import "ViewController.h"
#import "ImageUtil.h"
#import "ColorMatrix.h"
@interface ViewController ()<UIActionSheetDelegate>

@property (nonatomic, strong) UIImageView *filterView;

@property (nonatomic, strong) UILabel *filterLabel;

@end

@implementation ViewController

- (UIImageView *)filterView
{
    if (_filterView == nil) {
        _filterView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 50.0f, self.view.frame.size.width, 200.0f)];
        _filterView.userInteractionEnabled = YES;
        //contentMode是用来设置图片的显示方式,如居中、居右,是否缩放。
        //特别注意:UIViewContentModeScaleToFill属性会导致图片变形。UIViewContentModeScaleAspectFit会保证图片比例不变,而且全部显示在ImageView中,这意味着ImageView会有部分空白。UIViewContentModeScaleAspectFill也会证图片比例不变,但是是填充整个ImageView的,可能只有部分图片显示出来。
        //其它的当图片的大小超过屏幕的尺寸时,只有部分显示出来
        _filterView.contentMode = UIViewContentModeScaleToFill;
    }
    return _filterView;
}

- (UILabel *)filterLabel
{
    if (_filterLabel == nil) {
        _filterLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 300.0f, self.view.frame.size.width, 25.0f)];
        _filterLabel.backgroundColor = [UIColor clearColor];
        _filterLabel.textColor = [UIColor orangeColor];
        _filterLabel.textAlignment = NSTextAlignmentCenter;
    }
    return _filterLabel;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.title = @"滤镜";
    if ([[[UIDevice currentDevice] systemVersion] floatValue] > 7.0f) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }
    self.filterView.image = [UIImage imageNamed:@"622.png"];
    [self.view addSubview:self.filterView];
    
    self.filterLabel.text = @"原图";
    [self.view addSubview:self.filterLabel];
    
    UIButton *sender = [UIButton buttonWithType:UIButtonTypeCustom];
    [sender setTitle:@"滤镜" forState:UIControlStateNormal];
    sender.frame = CGRectMake(self.view.frame.size.width/2.0f - 50.0f, 350.0f, 100.0f, 30.0f);
    sender.backgroundColor = [UIColor redColor];
    sender.layer.cornerRadius = 5.0f;
    [sender addTarget:self action:@selector(senderAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:sender];
}

#pragma mark - senderAction 按钮点击事件
- (void)senderAction
{
    UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"滤镜" delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"原图",@"LOMO",@"黑白",@"复古",@"哥特",@"锐化",@"淡雅",@"酒红",@"清宁",@"浪漫",@"光晕",@"蓝调",@"梦幻",@"夜色", nil];
    [actionSheet showInView:self.view];
}

#pragma mark - UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString *str = @"";
    switch (buttonIndex) {
        case 0:
            str = @"原图";
            self.filterView.image = [UIImage imageNamed:@"622.png"];
            break;
        case 1:
            str = @"LOMO";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_lomo];
            break;
        case 2:
            str = @"黑白";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_heibai];
            break;
        case 3:
            str = @"复古";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_huajiu];
            break;
        case 4:
            str = @"哥特";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_gete];
            break;
        case 5:
            str = @"锐化";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_ruise];
            break;
        case 6:
            str = @"淡雅";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_danya];
            break;
        case 7:
            str = @"酒红";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_jiuhong];
            break;
        case 8:
            str = @"清宁";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_qingning];
            break;
        case 9:
            str = @"浪漫";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_langman];
            break;
        case 10:
            str = @"光晕";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_guangyun];
            break;
        case 11:
            str = @"蓝调";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_landiao];
            break;
        case 12:
            str = @"梦幻";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_menghuan];
            break;
        case 13:
            str = @"夜色";
            self.filterView.image = [ImageUtil imageWithImage:[UIImage imageNamed:@"622.png"] withColorMatrix:colormatrix_yese];
            break;
            
        default:
            break;
    }
    
    self.filterLabel.text = str;
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
View Code 基于 storyboard编写的 滤镜效果demo

代码:

#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------


#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------


#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (void)dealloc {
    [_window release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}
}//这里面并没有写一个 Self.window.rootViewController = xx.vc ;是因为用了storyBoard,然后修改了程序的主入口
View Code Appdelegate文件
#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------


#import <UIKit/UIKit.h>

@interface ContactListController : UITableViewController

@end


#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------
#import "ContactListController.h"
#import "DataBaseHelper.h"
#import "ContactDetailController.h"
#import "AddContactController.h"
#import "Contact.h"
#import "ContactListCell.h"
#import "FMDatabase.h"//第三方(数据库操作类)
#import "DataBaseHelper.h"


//指定代理对象所在的类服从协议_04
@interface ContactListController ()<updateDelegate>
@property (nonatomic, retain) FMDatabase *database;//存储数据库操作对象
@property (nonatomic, retain) NSMutableArray *dataSource;//存储数据源

@end

@implementation ContactListController
#pragma mark -lazy loading-
- (NSMutableArray *)dataSource {
    if (!_dataSource) {
        self.dataSource = [NSMutableArray arrayWithCapacity:0];
    }
    return [[_dataSource retain] autorelease];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.leftBarButtonItem = self.editButtonItem;
    //1.创建数据库
    [self createDataBase];
    //2.创建表
    [self createTable];
    //3.读取数据
    [self selectDataFromDataBase];
}

-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
    [super setEditing:editing animated:animated];
    if (!editing) {// NO 编辑完成
        self.view.userInteractionEnabled = NO;
        //将修改后的数据返回到上一个界面
        
    }
}
#pragma mark -handle DataBase -
- (void)createDataBase {
    //数据库操作对象
    self.database = [FMDatabase databaseWithPath:[self getFilePath]];
}
//创建表
- (void)createTable {
    //1.打开数据库
    if (![self.database open]) {
        return;
    }
    //2.通过SQL语句操作数据库 (创建表)
    //executeUpdate: 除了查询指令,其他的都用这个方法
    [self.database executeUpdate:@"create table if not exists Contacts(con_id integer primary key autoincrement, con_name text, con_gender text, con_age integer, con_phoneNum text, con_image blob)"];
    //3.关闭数据库
    [self.database close];
}
//读取数据
- (void)selectDataFromDataBase {
    //1.打开数据库
    if (![self.database open]) {
        return;
    }
    //2.通过SQL语句执行查询操作
    FMResultSet *result = [self.database executeQuery:@"select * from Contacts"];
    while ([result next]) {
        NSInteger ID = [result intForColumn:@"con_id"];
        NSString *name = [result stringForColumn:@"con_name"];
        NSString *gender = [result stringForColumn:@"con_gender"];
        NSInteger age = [result intForColumn:@"con_age"];
        NSString *phoneNum = [result stringForColumn:@"con_phoneNum"];
        NSData *data = [result dataForColumn:@"con_image"];
        UIImage *image = [UIImage imageWithData:data];
        //把数据封装到Contact对象里
        Contact *per = [[Contact alloc] initWithId:ID name:name gender:gender age:age phoneNum:phoneNum photoImage:image];
        //存放到数组中
        [self.dataSource addObject:per];
    }
    //3.关闭数据库
    [self.database close];
}

- (NSString *)getFilePath {
   NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSLog(@"%@", docPath);
    return [docPath stringByAppendingPathComponent:@"DB.sqlite"];
}

//插入一条数据
- (void)insertIntoDataBaseWithContact:(Contact *)contact {
    //1.打开数据库
    if (![self.database open]) {
        return;
    }
    //2.通过SQL语句操作数据库(插入一条数据)
    NSData *data = UIImagePNGRepresentation(contact.photoImage);
    
    [self.database executeUpdate:@"insert into Contacts(con_name, con_gender, con_age, con_phoneNum, con_image) values(?, ?, ?, ?, ?)", contact.name, contact.gender, @(contact.age), contact.phoneNum, data];
    //3.关闭数据库
    [self.database close];
} 


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#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 _dataSource.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ContactListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"reuse" forIndexPath:indexPath];
    Contact *per = self.dataSource[indexPath.row];
    // Configure the cell...
    cell.nameLabel.text = per.name;
    cell.phoneNumLabel.text = per.phoneNum;
    return cell;
}




// 提交编辑的方法
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
       //1.数据源的删除
        Contact * per = self.dataSource[indexPath.row];
        //从数据库删除该条数据
        [self deleteFromDataBaseWithContact:per];
        //从数组里移除
        [self.dataSource removeObjectAtIndex:indexPath.row];
        
       //2.界面的删除
        //当前只有一个分区,所以不判断分区
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
    
    }   
}
//删除一条数据
-(void)deleteFromDataBaseWithContact:(Contact *)contact{
    BOOL isOpen = [self.database open];
    if (!isOpen) {
        return;
    }
    [self .database executeUpdate:@"delete from Contacts where con_id = ?",@(contact.con_id)];
    //关闭数据库
    [self.database close];
}

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

//用于刷新数据
/*下面插入数据后已经刷新了数据
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.dataSource removeAllObjects];
    [self selectDataFromDataBase];
    [self.tableView reloadData];
    NSLog(@"%@@@@@",((Contact *)self.dataSource[0]).name);
}
*/

#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation


//使用 StoryBoard 进行页面跳转的时候,它会自动的走这个方法。在这个方法我们可以做一些需要的相应的操作方法。
//参数:第一个参数 segue 就是跳转的线 第二个参数 sender 就是我们跳转的时候要传的参数 destinationViewController是一个导航控制器。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
    __block ContactListController *vc = self;
    if ([segue.identifier isEqualToString:@"add"]) {
        AddContactController *addVC = [segue.destinationViewController viewControllers][0];
//        [segue.destinationViewController viewControllers][0]就是得到导航控制器所管理的视图控制器
        addVC.AddBlock = ^(Contact *contact) {
            //方到数组中
            [vc.dataSource addObject:contact];
            //本地数据持久化,放入本地数据库的表中
            [vc insertIntoDataBaseWithContact:contact];
            //刷新数据,界面就要重新读出页面的内容
            [vc.tableView reloadData];
        };
    } else {
//        ContactDetailController *detailVC = [[ContactDetailController alloc] init];
        ContactDetailController * detailVc = segue.destinationViewController;
        NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];//sender 此时是选中的cell
        //属性传值
        detailVc.contact = self.dataSource[indexPath.row];
        //设置代理对象_03
        detailVc.delegate = self;
        
    }
}

//实现协议_05
-(void)updateDataWithContact:(Contact *)contact{
    //执行更新操作 跟新数据库表里的信息
    [self updateFromDataBaseWithContact:contact];
    NSLog(@"//执行更新操作 跟新数据库表里的信息");
    //刷新数据
    [self.tableView reloadData];
}

//更新一条数据
- (void)updateFromDataBaseWithContact:(Contact *)contact{
    //1.打开数据库
    BOOL isOpen = [self.database open];
    if (!isOpen) {
        return;
    }
    NSData * data = UIImagePNGRepresentation(contact.photoImage);
    //2.执行SQL语句操作数据库
    BOOL isSuccess =[self.database executeUpdate:@"update Contacts set con_name = ?, con_gender = ?,con_age = ?,con_phoneNum = ?,con_image = ? where con_id = ?",contact.name,contact.gender,@(contact.age),contact.phoneNum,data,@(contact.con_id)];//注意把 age 转化为对象
    if (isSuccess) {
        NSLog(@"%@",isSuccess ? @"更新成功":@"更新失败");
    }else{
        NSLog(@"失败");
    }
    //3.关闭数据库
    [self.database close];
}
/*
 数据库操作类
 数据库查询类
 数据库在多线程下的操作类
 
 使用 FMDB
 FMDatabase :1.创建数据库,我们只需要提供一个数据库路径
             2.创建表
             3.用数据库对象去执行相应的操作 executeUpdate(只能操作对象)  executeQure
               操作有,创建表,增删改查
                 1).打开数据库
                 2).通过给定的SQL语句操作数据库
                 3).关闭数据库
 */

@end
View Code ContactListController文件
#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------


#import <UIKit/UIKit.h>
#import "Contact.h"

//指定代理协议_01
@protocol updateDelegate <NSObject>

-(void)updateDataWithContact:(Contact *)contact;

@end

//下面属性是从 storyBoard 里面关联的属性
@interface ContactDetailController : UIViewController
@property (retain, nonatomic) IBOutlet UITextField *nameTf;
@property (retain, nonatomic) IBOutlet UITextField *genderLabel;
@property (retain, nonatomic) IBOutlet UITextField *phonelabel;
@property (retain, nonatomic) IBOutlet UIImageView *phontoView;

//定义代理属性_02  注意这里不写 copy 要写 assign  Block 中需要为 Copy
@property(nonatomic,assign)id<updateDelegate>delegate;

//定义属性 接收首页传来的model
@property (nonatomic, retain) Contact *contact;
@end


#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------



#import "ContactDetailController.h"

@interface ContactDetailController ()

@end

@implementation ContactDetailController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
    self.view.userInteractionEnabled = NO;
    self.nameTf.text = self.contact.name;
    self.phonelabel.text = self.contact.phoneNum;
    self.phontoView.image = self.contact.photoImage;
}
-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
    [super setEditing:editing animated:animated];
    self.view.userInteractionEnabled = editing;//根据参数去确定用户是否可以操作控件的编辑
    if (!editing) {
        //将修改后的联系人返回到上一界面
//        NSString * name = self.nameTf.text;
//        NSString * gender = self.genderLabel.text;
//        NSString * phoneNum = self.phonelabel.text;
//        UIImage * image = self.phontoView.image;
//        Contact * per = [[Contact alloc]initWithId:self.contact.con_id name:name gender:gender age:10 phoneNum:phoneNum photoImage:image];//这是新建的一个
        //优化
        self.contact.name = self.nameTf.text;
        self.contact.gender = self.genderLabel.text;
        self.contact.phoneNum = self.phonelabel.text;
        self.contact.photoImage =self.phontoView.image;
        //传回到上一界面_06
        if (self.delegate && [self.delegate respondsToSelector:@selector(updateDataWithContact:)]) {
//            [self.delegate updateDataWithContact:per];
            [self.delegate updateDataWithContact:self.contact];
        }else{
            NSLog(@"错误的");
        }
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (void)dealloc {
    [_nameTf release];
    [_genderLabel release];
    [_phonelabel release];
    [_phontoView release];
    [super dealloc];
}
@end
View Code ContactDetailController文件
#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------

#import <UIKit/UIKit.h>
@class Contact;
@interface AddContactController : UIViewController

@property (nonatomic, copy) void(^AddBlock)(Contact *);


@end



#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------

//
//  AddContactController.m

#import "AddContactController.h"
#import "Contact.h"

@interface AddContactController ()
@property (retain, nonatomic) IBOutlet UIImageView *photoImageView;
@property (retain, nonatomic) IBOutlet UITextField *nameTF;
@property (retain, nonatomic) IBOutlet UITextField *genderTF;
@property (retain, nonatomic) IBOutlet UITextField *phoneTF;

@end

@implementation AddContactController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (IBAction)handleCancel:(id)sender {
    if (![self.nameTF.text isEqualToString:@""] || ![self.phoneTF.text isEqualToString:@""]) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"确定放弃保存吗" delegate:self cancelButtonTitle:@"" otherButtonTitles:@"确定", nil];
        [alert show];
        [alert release];
        //其他操作
    }else if ([self.nameTF.text isEqualToString:@""] && [self.phoneTF.text isEqualToString:@""]) {
        NSLog(@"返回返回");
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];
    }
}
- (IBAction)handelDone:(id)sender {
    NSString *name = self.nameTF.text;
    NSString *gender = self.genderTF.text;
    NSString *phone = self.phoneTF.text;
    Contact *contact = [[Contact alloc] initWithId:0 name:name gender:gender age:12 phoneNum:phone photoImage:nil];
        //传到上一界面
    self.AddBlock(contact);
    
    /*
    if ([self.nameTF.text isEqualToString:@""] && [self.phoneTF.text isEqualToString:@""]) {
        [self dismissViewControllerAnimated:YES completion:^{
            
        }];
    }
     */
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (void)dealloc {
    [_photoImageView release];
    [_nameTF release];
    [_genderTF release];
    [_phoneTF release];
    [super dealloc];
}
@end
View Code AddContactController文件
#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------


#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface Contact : NSObject
@property (nonatomic, assign) NSInteger con_id;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *gender;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *phoneNum;
@property (nonatomic, retain) UIImage *photoImage;

//初始化方法
- (instancetype)initWithId:(NSInteger)ID name:(NSString *)name gender:(NSString *)gender age:(NSInteger )age phoneNum:(NSString *)phoneNum photoImage:(UIImage *)photoImage;


@end


#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------


#import "Contact.h"

@implementation Contact
- (instancetype)initWithId:(NSInteger)ID name:(NSString *)name gender:(NSString *)gender age:(NSInteger)age phoneNum:(NSString *)phoneNum photoImage:(UIImage *)photoImage {
    self = [super init];
    if (self) {
        self.con_id = ID;
        self.name = name;
        self.gender = gender;
        self.age = age;
        self.phoneNum = phoneNum;
        self.photoImage = photoImage;
    }
    return self;
}

- (void)dealloc {
    self.name = nil;
    self.gender = nil;
    self.phoneNum = nil;
    self.photoImage = nil;
    [super dealloc];
}
@end
View Code Contact文件
#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------

#import <UIKit/UIKit.h>

@interface ContactListCell : UITableViewCell

@property (retain, nonatomic) IBOutlet UIImageView *photoImage;
@property (retain, nonatomic) IBOutlet UILabel *nameLabel;
@property (retain, nonatomic) IBOutlet UILabel *phoneNumLabel;
@end


#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------

#import "ContactListCell.h"

@implementation ContactListCell

- (void)awakeFromNib {
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)dealloc {
    [_photoImage release];
    [_nameLabel release];
    [_phoneNumLabel release];
    [super dealloc];
}
@end
View Code ContactListCell文件
#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------

#import <Foundation/Foundation.h>
#import <sqlite3.h>
/**
 *  该类是数据库管理类。提供两个功能:
 1.打开数据库
 2.关闭数据库
 
 导入libsqlite3.0.dylib动态链接库,然后导入sqlite3.h头文件
 */
@interface DataBaseManager : NSObject
//打开数据库
+ (sqlite3 *)openDataBase;

//关闭数据库
+ (void)closeDataBase;

@end


#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------


#import "DataBaseManager.h"

static sqlite3 *db = nil;//存储数据库对象

@implementation DataBaseManager
//打开数据库

+ (sqlite3 *)openDataBase {
    //优化 对于数据库操作,我们只打开一次数据库就可以了。
    //如果sqlite对象不为空,说明之前打开过,直接返回数据库地址就可以了。
    if (db) {
        return db;
    }
    
    //1.获取数据库文件的路径
    NSString *filePath = [self getFilePath];
    //2.打开数据库
    sqlite3_open([filePath UTF8String], &db);
    return db;
}

//关闭数据库
+ (void)closeDataBase {
    if (db) {
        sqlite3_close(db);
        db = nil;
    }
}

+ (NSString *)getFilePath {
    //1.获取Documents文件夹路径
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSLog(@"%@", path);
    //2.拼接上数据文件的路径
    NSString *dataPath = [path stringByAppendingPathComponent:@"DB.sqlite"];
    return dataPath;
}

@end
View Code DataBaseManager文件
#pragma mark (.h文件)--------------------------------------------------------------------------------------------------------

#import <Foundation/Foundation.h>
#import <sqlite3.h>
@class Contact;
/**
 *  数据库的操作类
    对数据库进行创建表,插入,删除,更新,查询操作,从数据库获取数据,处理数据
 */
@interface DataBaseHelper : NSObject
//单例方法
+ (DataBaseHelper *)defaultDBHelper;

+ (void)createTableInDataBase;//创建表的操作

+ (void)selectFromDataBase;  //查询数据的操作

+ (void)insertIntoDataBaseWithContact:(Contact *)contact; //插入一条数据的操作

+ (void)updateFromDataBaseWithContact:(Contact *)contact; //更新一条数据的操作

+ (void)deleteFromDataBaseWithContact:(Contact *)contact; //删除一条数据的操作
//获取唯一的标识
+ (NSInteger)getNumber;


//提供相应的方法给对应的controller

@end

//添加分类 用于创建指令集
@interface DataBaseHelper (CreateStatement)
+ (sqlite3_stmt *)createTableStatement;
+ (sqlite3_stmt *)insertStatement;
+ (sqlite3_stmt *)updateStatement;
+ (sqlite3_stmt *)selectStatement;
+ (sqlite3_stmt *)deleteStatement;
/*
1.打开数据库
2.创建指令集
3.创建SQL语句
4.语法检查
 */
@end


#pragma mark (.m文件)--------------------------------------------------------------------------------------------------------

#import "DataBaseHelper.h"
#import "DataBaseManager.h"
#import "Contact.h"
/**
 *  1.打开数据库
    2.创建指令集
    3.创建SQL语句
    4.语法检查
    5.获取指令集
    (6.如果有参数,需要绑定参数)
    7.执行SQL语句
    8.释放资源
    9.关闭数据库
 */
@implementation DataBaseHelper
//单例方法
static DataBaseHelper *helper = nil;
+ (DataBaseHelper *)defaultDBHelper {
    @synchronized(self) {
        if (!helper) {
            helper = [[DataBaseHelper alloc] init];
            //程序每次运行,只从数据库里读取一次数据即可
            [self createTableInDataBase];//创建表
            [self selectFromDataBase];//读取数据
        }
    }
    return helper;
}
//创建表的操作
+ (void)createTableInDataBase {
    //5.获取指令集
    sqlite3_stmt *stmt = [self createTableStatement];
    //6.如果有参数,需要绑定参数
    //7.执行SQL语句 执行数据库操作
    if (sqlite3_step(stmt) == SQLITE_DONE) {
        NSLog(@"创建表成功");
    }
    //8.释放资源
    sqlite3_finalize(stmt);
    //9.关闭数据库
    [DataBaseManager closeDataBase];
}

+ (void)selectFromDataBase {
    
}
//插入
+ (void)insertIntoDataBaseWithContact:(Contact *)contact {
    //5.获取指令集
    sqlite3_stmt *stmt = [self insertStatement];
    //(6.如果有参数,需要绑定参数)
    //第一个:指令集; 第二个:第几个问号; 第三个:绑定的数据
    
    sqlite3_bind_int(stmt, 1, (int)contact.con_id);
    //第一个:指令集; 第二个:第几个问号; 第三个:绑定的数据; 第四个:是否限制长度 第五个:预留参数
    sqlite3_bind_text(stmt, 2, [contact.name UTF8String], -1, nil);
    sqlite3_bind_text(stmt, 3, [contact.gender UTF8String], -1, nil);
    sqlite3_bind_int(stmt, 4, (int)contact.age);
    sqlite3_bind_text(stmt, 5, [contact.phoneNum UTF8String], -1, nil);
    

    NSData *data = UIImagePNGRepresentation(contact.photoImage);
    //绑定二进制数据
    sqlite3_bind_blob(stmt, 6, data.bytes, (int)data.length, nil);
    
    //7.执行SQL语句
    if (sqlite3_step(stmt) == SQLITE_DONE) {
        NSLog(@"插入数据成功");
    }
    //8.释放资源
    sqlite3_finalize(stmt);
    //9.关闭数据库
    [DataBaseManager closeDataBase];
}

+ (void)updateFromDataBaseWithContact:(Contact *)contact {
    //5.获取更新数据指令集
    sqlite3_stmt *stmt = [self updateStatement];
    //6.绑定参数 01:指令集 02:第几个问号 03:绑定的数据
    //01 指令集 02第几个问号 03绑定的数据(C语言) 04是否限制长度 05预留参数
    sqlite3_bind_text(stmt, 1, [contact.name UTF8String], -1, nil);
    sqlite3_bind_text(stmt, 2, [contact.gender UTF8String], -1, nil);
    sqlite3_bind_int(stmt, 3, (int)contact.age);
    sqlite3_bind_text(stmt, 4, [contact.phoneNum UTF8String], -1, nil);
    
    //绑定二进制数据
    NSData *data = UIImagePNGRepresentation(contact.photoImage);
    sqlite3_bind_blob(stmt, 5, data.bytes, (int)data.length, nil);
    
    sqlite3_bind_int(stmt, 6, (int)contact.con_id);
    
    //7.执行SQL语句
    if (sqlite3_step(stmt) == SQLITE_DONE) {
        NSLog(@"修改数据成功");
    }
    //8.释放资源
    sqlite3_finalize(stmt);
    //9.关闭数据库
    [DataBaseManager closeDataBase];
}

+ (void)deleteFromDataBaseWithContact:(Contact *)contact {
    sqlite3_stmt *stmt = [self deleteStatement];
    sqlite3_bind_int(stmt, 1, (int)contact.con_id);
    if (sqlite3_step(stmt) == SQLITE_DONE) {
        NSLog(@"删除数据成功");
    }
    sqlite3_finalize(stmt);
    [DataBaseManager closeDataBase];

}
//获取唯一的标识
//+ (NSInteger)getNumber {
//    
//}

@end


//分类的实现部分
@implementation DataBaseHelper (CreateStatement)
+ (sqlite3_stmt *)createTableStatement {
    //1.打开数据库
    sqlite3 *db = [DataBaseManager openDataBase];
    //2.创建指令集
    sqlite3_stmt *stmt = nil;
    //3.创建SQL语句
    NSString *creatTable = @"create table if not exists Contact(con_id integer primary key autoincrement, con_name text, con_gender text, con_age integer, con_phoneNum text, con_image blob)";
    //4.语法检查 检查数据库是否打开成功,检查SQL语句是否正确
    /**
     *  第一个参数:数据库对象
        第二个参数:SQL语句,
        第三个参数:是否限制SQL语句的长度
        第四个参数:指令集地址
        第五个参数:预留参数
     */
    int flag = sqlite3_prepare_v2(db, [creatTable UTF8String], -1, &stmt, 0);
    if (flag == SQLITE_OK) {
        NSLog(@"创建表的指令集成功");
    }
    return stmt;//返回指令集
}

+ (sqlite3_stmt *)insertStatement {
    //1.打开数据库
    sqlite3 *db = [DataBaseManager openDataBase];
    //2.创建指令集
    sqlite3_stmt *stmt = nil;
    //3.创建SQL语句
    NSString *insertSQL = @"insert into Contact(con_id, con_name, con_gender, con_age, con_phoneNum, con_image) values(?, ?, ?, ?, ?, ?)";
    //4.语法检查
    int flag = sqlite3_prepare_v2(db, [insertSQL UTF8String], -1, &stmt, 0);
    if (flag == SQLITE_OK) {
        NSLog(@"插入语法正确");
    }
    return stmt;
    
}
+ (sqlite3_stmt *)updateStatement {
    sqlite3 *db = [DataBaseManager openDataBase];
    NSString *updateSQL = @"update Contact set con_name = ?, con_gender = ?, con_age = ?, con_phone = ?, con_image = ? where con_id = ?";
    sqlite3_stmt *stmt = nil;
    int flag = sqlite3_prepare_v2(db, [updateSQL UTF8String], -1, &stmt, 0);
    if (SQLITE_OK == flag) {
        NSLog(@"更新数据成功");
    }
    return stmt;
}
+ (sqlite3_stmt *)selectStatement {
    sqlite3 *db = [DataBaseManager openDataBase];
    NSString *selectSQL = @"select * from Contact";
    sqlite3_stmt *stmt = nil;
    int flag = sqlite3_prepare_v2(db, [selectSQL UTF8String], -1, &stmt, 0);
    if (SQLITE_OK == flag) {
        NSLog(@"查询数据成功");
    }
    return stmt;
}
+ (sqlite3_stmt *)deleteStatement {
    sqlite3 *db = [DataBaseManager openDataBase];
    NSString *deleteSQL = @"delete from Contact where con_id = ?";
    sqlite3_stmt *stmt = nil;
    int flag = sqlite3_prepare_v2(db, [deleteSQL UTF8String], -1, &stmt, 0);
    if (SQLITE_OK == flag) {
        NSLog(@"删除数据成功");
    }
    return stmt;
}


@end
View Code DataBaseHelper文件

数据库更新操作的时候,注意是对对象的更新,如果不是对象,就要转化为对象(因为底层是用C语言写的)。

添加联系人我们用的是 Block传值。

我们使用第三方数据库操作类 FMDB 的步骤:

#import "FMDatabase.h" 数据库操作类

#import "FMResultSet.h" 数据库查询类

#import "FMDatabaseAdditions.h" 数据库其他附加方法

#import "FMDatabaseQueue.h"线程下的数据库操作类

#import "FMDatabasePool.h"数据库在多线程下的操作类

  使用 FMDB

 FMDatabase :1.创建数据库,我们只需要提供一个数据库路径

             2.创建表

             3.用数据库对象去执行相应的操作 executeUpdate(只能操作对象)  executeQure

               操作有,创建表,增删改查

                 1).打开数据库

                 2).通过给定的SQL语句操作数据库

                 3).关闭数据库

 

一定要掌握下面的操作方法

*****************************************

*CocoaPods快速引入第三方类:
cd 拖入文件(cd 与文件名中间有空格)
pod init
pod search 需要引入的类
然后再podfile文件中粘贴上类的版本号
pod install --verbose --no-repo-update
*****************************************

注意:对于属性的属性在定义代理的属性的时候要使用 assign ;在使用Block 的时候要使用Copy

原文地址:https://www.cnblogs.com/benpaobadaniu/p/4855334.html