zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Java深层复制方式
    手机浏览器点击时出现蓝色边框解决办法
    刷新iframe
    sass mixin 持续更新
    自动设置 rem es模块写法
    vue-cli安装sass
    URL转码
    H5单文件压缩插件
    文件跨域上传问题
    HTML,CSS,font-family:中文字体的英文名称【转载】
  • 原文地址:https://www.cnblogs.com/benpaobadaniu/p/4855334.html
Copyright © 2011-2022 走看看