iOS中SQLite使用
创建数据表
CREATE TABLE CONTACTS(ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT ,ADDRESS TEXT);
向数据表中添加数据
INSERT INTO CONTACTS (NAME ,ADDRESS) VALUES ("张三","铁龙路");
从数据表中删除数据
DELETE FROM CONTACTS WHERE NAME = "张三";
修改数据表中的数据
UPDATE CONTACTS SET NAME = "王五" WHERE NAME = "张三";
读取数据表
SELECT * FROM CONTACTS;
mac上的命令行操作使用测试
sqlite3 contacts.sql
数据库文件由内容才会创建数据库表
命令行继续输入:
CREATE TABLE CONTACTS ( //回车
ID INTEGER PRIMARY KEY AUTOINCREMENT, //回车
NAME TEXT, 回车
PHONE TEXT);
效果如图
2执行插入语句
INSERT INTO CONTACTS (NAME, PHONE) VALUES ("张三","18201430000");
查询语句
SELECT * FROM CONTACTS;
效果
1|张三|18201430000
3
更新语句
UPDATE CONTACTS SET NAME = "王五" WHERE NAME = "张三";
查看语句
SELECT * FROM CONTACTS;
4
删除语句
DELETE FROM CONTACTS WHERE NAME = '"王五";
查看语句
SELECT * FROM CONTACTS;
效果
6iOS中使用sqlite,担心表述不清楚,demo拉取地址:
https://gitee.com/xgkp/sqliteDemo.git
创建一个空的工程名字叫sqliteDemo
Targets - gengral -Linked Frameworks andLibraries + 输入 sqlite 选择 libsqlite3.tbd - add
7在viewcontroller中导入头文件
#import <sqlite3.h>
接下来进行代码实现
初始化数据库存放的路径
-(NSString *)sqliteFilePath{
// 获取cache目录
NSString * cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// 拼接文件名字
NSString * databasePath = [cachePath stringByAppendingString:@"contacts.sqlite"];
return databasePath;
}
打开数据库
// 获取数据库文件路径
NSString * dbFilePath = [self sqliteFilePath];
// 将路径字符串转化成UTF-8
char* dbPath = [dbFilePath UTF8String];
//声明sqlite数据库结构体的指针
sqlite3* contactDB;
// sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)
// sqlite3_open(dbPath, &contactDB)表示打开dbPath路径下的数据库,如果不存在,则创建它
if(sqlite3_open(dbPath, &contactDB) == SQLITE_OK){
NSLog(@"数据库打开成功");
}else
{
NSLog(@"数据库打开失败");
}
生成指令数据库操作,创建数据表
// 生成指令
// 创建数组
char sqlite_stmt[1000];
// 向数组填充字符串
snprintf(sqlite_stmt, 1000,
"CREATE TABLE CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)");
//执行语句
// 第一个参数,数据库结构体指针
// 第二个参数,sqlite语句
// 第三个参数和第四个参数,回调方法NULL表示不使用回调
// 第五个参数,返回错误信息NULL表示不使用错误信息
// sqlite3_exec(<#sqlite3 *#>, <#const char *sql#>, <#int (*callback)(void *, int, char **, char **)#>, <#void *#>, <#char **errmsg#>)
if(sqlite3_exec(contactDB, sqlite_stmt, NULL, NULL, NULL) == SQLITE_OK){
NSLog(@"创建表成功");
}else
{
NSLog(@"创建表失败");
}
关闭数据库
//关闭数据库,释放资源
// sqlite3_close(<#sqlite3 *#>)
sqlite3_close(contactDB);
增删改查的基本操作
向数据表中增加一条数据,注意C语言指令的双引号""前面要用反斜杠/来进行转义
// 常规操作,打开数据库
// 获取数据库文件路径
NSString * dbFilePath = [self sqliteFilePath];
// 将路径字符串转化成UTF-8
char* dbPath = [dbFilePath UTF8String];
//声明sqlite数据库结构体的指针
sqlite3* contactDB;
// sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)
// sqlite3_open(dbPath, &contactDB)表示打开dbPath路径下的数据库,如果不存在,则创建它
if(sqlite3_open(dbPath, &contactDB) == SQLITE_OK){
NSLog(@"数据库打开成功");
}else
{
NSLog(@"数据库打开失败");
}
// 常规操作,打开数据库
//创建指令
char sqlite_stmt[1000];
snprintf(sqlite_stmt, 1000,
"INSERT INTO CONTACTS (NAME, ADDRESS, PHONE) VALUES (\"张三\",\"铁龙路\",\"18201430000\")");
// 执行指令
if (sqlite3_exec(contactDB, sqlite_stmt, NULL, NULL, NULL) == SQLITE_OK) {
NSLog(@"插入数据成功");
}else
{
NSLog(@"插入数据失败");
}
// 关闭数据库
sqlite3_close(contactDB);
同理,如果希望删除数据可以直接修改C语言数组中存放的指令即可。
删除数据的具体代码实现
// 常规操作,打开数据库
// 获取数据库文件路径
NSString * dbFilePath = [self sqliteFilePath];
// 将路径字符串转化成UTF-8
char* dbPath = [dbFilePath UTF8String];
//声明sqlite数据库结构体的指针
sqlite3* contactDB;
// sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)
// sqlite3_open(dbPath, &contactDB)表示打开dbPath路径下的数据库,如果不存在,则创建它
if(sqlite3_open(dbPath, &contactDB) == SQLITE_OK){
NSLog(@"数据库打开成功");
}else
{
NSLog(@"数据库打开失败");
}
// 常规操作,打开数据库
//创建指令
char sqlite_stmt[1000];
snprintf(sqlite_stmt, 1000,
"DELETE FROM CONTACTS WHERE NAME = \"张三\"");
// 执行指令
if (sqlite3_exec(contactDB, sqlite_stmt, NULL, NULL, NULL) == SQLITE_OK) {
NSLog(@"删除数据成功");
}else
{
NSLog(@"删除数据失败");
}
// 关闭数据库
sqlite3_close(contactDB);
修改数据
-(void)updateRow
{
// 常规操作,打开数据库
// 获取数据库文件路径
NSString * dbFilePath = [self sqliteFilePath];
// 将路径字符串转化成UTF-8
char* dbPath = [dbFilePath UTF8String];
//声明sqlite数据库结构体的指针
sqlite3* contactDB;
// sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)
// sqlite3_open(dbPath, &contactDB)表示打开dbPath路径下的数据库,如果不存在,则创建它
if(sqlite3_open(dbPath, &contactDB) == SQLITE_OK){
NSLog(@"数据库打开成功");
}else
{
NSLog(@"数据库打开失败");
}
// 常规操作,打开数据库
//创建指令
char sqlite_stmt[1000];
snprintf(sqlite_stmt, 1000,
"UPDATE CONTACTS SET NAME = \"李四\" WHERE NAME = \"张三\"");
// 执行指令
if (sqlite3_exec(contactDB, sqlite_stmt, NULL, NULL, NULL) == SQLITE_OK) {
NSLog(@"修改数据成功");
}else
{
NSLog(@"修改数据失败");
}
// 关闭数据库
sqlite3_close(contactDB);
}
数据库的读取会有所不同,因为数据库读取时候可能会有多条语句,或者是返回的数据需要遍历处理
数据库的读取,具体实现
// 读取数据库可能有多条语句,所以语句有所不同
// 常规操作,打开数据库
// 获取数据库文件路径
NSString * dbFilePath = [self sqliteFilePath];
// 将路径字符串转化成UTF-8
char* dbPath = [dbFilePath UTF8String];
//声明sqlite数据库结构体的指针
sqlite3* contactDB;
// sqlite3_open(<#const char *filename#>, <#sqlite3 **ppDb#>)
// sqlite3_open(dbPath, &contactDB)表示打开dbPath路径下的数据库,如果不存在,则创建它
if(sqlite3_open(dbPath, &contactDB) == SQLITE_OK){
NSLog(@"数据库打开成功");
}else
{
NSLog(@"数据库打开失败");
}
// 常规操作,打开数据库
char sqlite_stmt[1000];
// 生成指令
snprintf(sqlite_stmt, 1000, "SELECT * FROM CONTACTS");
// 准备一个SQLite语句,用于执行
sqlite3_stmt * statement;
sqlite3_prepare_v2(contactDB, sqlite_stmt, -1, &statement, NULL);
// 执行语句,如果找到一行的匹配数据,c则返回SQLITE_ROW
while (sqlite3_step(statement) == SQLITE_ROW) {
// 获取到一行数据
NSInteger index = sqlite3_column_int(statement, 0);
NSString * name = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_text(statement, 1)];
NSString * address = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_text(statement, 2)];
NSString * phone = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_text(statement, 3)];
NSLog(@"%ld | %@ | %@ | %@",index,name,address,phone);
}
NSLog(@"数据库读取完毕");
// C语言操作,需要清理内存,清理掉之前正准备的语
sqlite3_finalize(statement);
// 关闭数据库
sqlite3_close(contactDB);
实际开发中的单例模式和model的简单实现
创建Demo名字是Vegetables,操作导入sqlite3步骤同上。
代码拉取地址:
https://gitee.com/xgkp/Vegetables.git
创建一个继承于NSObject的类Vegetable,Vegetable.h文件实现
@property (nonatomic,strong) NSString *name;
@property (nonatomic,assign) double price;
创建一个单例类名是VegetableManager,VegetableManager.h中实现
#import <Foundation/Foundation.h>
#import "Vegetable.h"
NS_ASSUME_NONNULL_BEGIN
@interface VegetableManager : NSObject
+(instancetype)sharedInstance;
//查询蔬菜
-(NSArray *)vegetables;
//添加蔬菜
-(BOOL)addvegetable:(Vegetable *)vegetable;
//删除蔬菜
-(BOOL)removeVegetableWihtName:(NSString *)vegetableName;
//修改价格
-(BOOL)changePrice:(double )price Name:(NSString *)vegName;
@end
NS_ASSUME_NONNULL_END
.m中的实现
#import "VegetableManager.h"
#import <sqlite3.h>
@interface VegetableManager()
@property (nonatomic,strong) NSArray *vegetabsArr;
@end
@implementation VegetableManager
+(instancetype)sharedInstance{
static VegetableManager * instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[super alloc] initWithUniqueInstance];
});
return instance;
}
//单例模式初始化
-(instancetype)initWithUniqueInstance
{
if (self = [super init]) {
//判断数据库文件是否存在,
NSString * sqlitePath = [self sqlitePath];
BOOL fileExist = [[NSFileManager defaultManager] fileExistsAtPath:sqlitePath];
if (!fileExist) {
// 文件不存在,创建数据库文件,添加数据表
const char* dbaPath = [sqlitePath UTF8String];
// 声明一个sqlite数据库结构体指针
sqlite3* vegetableDB;
// 打开数据库文件,没有则创建
if (sqlite3_open(dbaPath, &vegetableDB) == SQLITE_OK) {
NSLog(@"数据库文件打开、创建成功");
}else
{
NSLog(@"数据库文件打开、创建失败");
return nil;
}
// 执行创建表的操作
char sql_stmt[1000] = "CREATE TABLE VEGETABLES (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT,PRICE REAL)";
//执行语句
if (sqlite3_exec(vegetableDB, sql_stmt, NULL, NULL, NULL) == SQLITE_OK) {
NSLog(@"创建数据表成功");
sqlite3_close(vegetableDB);
}else
{
NSLog(@"创建数据表失败");
sqlite3_close(vegetableDB);
return nil;
}
}else
{
// 数据库文件存在,读取数据
[self readVegetablesListFromSqlite];
}
}
return self;
}
//数据库文件路径
-(NSString *)sqlitePath{
// 获取cache目录
NSString * catchPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// 拼接数据库文件名字
NSString * dbPath = [catchPath stringByAppendingPathComponent:@"vegetables.sqlite"];
return dbPath;
}
//从数据库中读取蔬菜信息到内存中
-(void)readVegetablesListFromSqlite
{
const char* dbaPath = [[self sqlitePath] UTF8String];
// 声明一个sqlite数据库结构体指针
sqlite3* vegetableDB;
// 打开数据库文件,没有则创建
if (sqlite3_open(dbaPath, &vegetableDB) == SQLITE_OK) {
NSLog(@"数据库文件打开、创建成功");
}else
{
NSLog(@"数据库文件打开、创建失败");
return ;
}
NSMutableArray * vegetableArr = [NSMutableArray array];
sqlite3_stmt * statement;
char sql_stmt[1000] = "SELECT ID, NAME, PRICE FROM VEGETABLES";
// 准备SQL语句
sqlite3_prepare_v2(vegetableDB, sql_stmt, -1, &statement, NULL);
while (sqlite3_step(statement) == SQLITE_ROW) {
// NSInteger index = sqlite3_column_int(statement, 0);
NSString * name = [[NSString alloc] initWithUTF8String:(const char*)sqlite3_column_text(statement, 1)];
double price = sqlite3_column_double(statement, 2);
Vegetable * vegModel = [[Vegetable alloc] init];
vegModel.name = name;
vegModel.price = price;
[vegetableArr addObject:vegModel];
}
NSLog(@"数据库读取完毕");
_vegetabsArr = [vegetableArr copy];
sqlite3_finalize(statement);
sqlite3_close(vegetableDB);
}
//返回蔬菜列表
-(NSArray *)vegetables
{
return [_vegetabsArr copy];
}
//判断蔬菜名称是否在列表中
-(BOOL)isInListForVegetableName:(NSString *)name
{
for (Vegetable * vegModel in _vegetabsArr) {
if ([vegModel.name isEqualToString:name]) {
return YES;
}
}
return NO;
}
//添加蔬菜
-(BOOL)addvegetable:(Vegetable *)vegetable
{
if ([self isInListForVegetableName:vegetable.name]) {
NSLog(@"已经存在这个蔬菜");
return NO;
}
if (vegetable.name.length == 0 || vegetable.price <=0) {
NSLog(@"蔬菜信息有误");
return NO;
}
const char* dbaPath = [[self sqlitePath] UTF8String];
// 声明一个sqlite数据库结构体指针
sqlite3* vegetableDB;
// 打开数据库文件,没有则创建
if (sqlite3_open(dbaPath, &vegetableDB) == SQLITE_OK) {
NSLog(@"数据库文件打开、创建成功");
}else
{
NSLog(@"数据库文件打开、创建失败");
return NO;
}
// 创建NSString类型的命令
NSString * command = [NSString stringWithFormat:@"INSERT INTO VEGETABLES (NAME, PRICE) VALUES (\"%@\",%lf)",vegetable.name,vegetable.price];
const char* sql_stmt = [command UTF8String];
if (sqlite3_exec(vegetableDB, sql_stmt, NULL, NULL, NULL) == SQLITE_OK) {
NSLog(@"添加蔬菜成功");
sqlite3_close(vegetableDB);
[self readVegetablesListFromSqlite];
return YES;
}else
{
NSLog(@"添加蔬菜失败");
sqlite3_close(vegetableDB);
return NO;
}
}
//删除蔬菜的方法
-(BOOL)removeVegetableWihtName:(NSString *)vegetableName
{
if (![self isInListForVegetableName:vegetableName]) {
NSLog(@"找不到要删除的蔬菜");
return NO;
}
// 打开库数据库文件
const char* dbPath = [[self sqlitePath] UTF8String];
// 声明一个sqlite数据库结构体指针
sqlite3* vegetableDB;
// 打开数据库文件,没有则创建
if (sqlite3_open(dbPath, &vegetableDB) == SQLITE_OK) {
NSLog(@"打开数据库创建成功");
}else
{
NSLog(@"数据库打开失败");
return NO;
}
// 拼接sqlite语句
NSString * command = [NSString stringWithFormat:@"DELETE FROM VEGETABLES WHERE NAME = \"%@\"",vegetableName];
const char* sql_stmt = [command UTF8String];
if (sqlite3_exec(vegetableDB, sql_stmt, NULL, NULL, NULL) == SQLITE_OK) {
NSLog(@"添加蔬菜成功");
sqlite3_close(vegetableDB);
[self readVegetablesListFromSqlite];
return YES;
}else
{
NSLog(@"添加蔬菜失败");
sqlite3_close(vegetableDB);
return NO;
}
}
//修改蔬菜价格
-(BOOL)changePrice:(double )price Name:(NSString *)vegName{
if (![self isInListForVegetableName:vegName]) {
NSLog(@"找不到要修改的蔬菜");
return NO;
}
// 打开库数据库文件
const char* dbPath = [[self sqlitePath] UTF8String];
// 声明一个sqlite数据库结构体指针
sqlite3* vegetableDB;
// 打开数据库文件,没有则创建
if (sqlite3_open(dbPath, &vegetableDB) == SQLITE_OK) {
NSLog(@"打开数据库创建成功");
}else
{
NSLog(@"数据库打开失败");
return NO;
}
// 拼接sqlite语句
NSString * command = [NSString stringWithFormat:@"UPDATE VEGETABLES SET PRICE = %lf WHERE NAME = \"%@\"",price,vegName];
const char* sql_stmt = [command UTF8String];
if (sqlite3_exec(vegetableDB, sql_stmt, NULL, NULL, NULL) == SQLITE_OK) {
NSLog(@"修改蔬菜价格成功");
sqlite3_close(vegetableDB);
[self readVegetablesListFromSqlite];
return YES;
}else
{
NSLog(@"修改蔬菜价格失败");
sqlite3_close(vegetableDB);
return NO;
}
}
@end
main.StoryBoard中添加一个tableView,并拖线到viewcontroller中
main.StoryBorad中点击mac导航中的Editor-Embed In - Navigation Controller
viewcontroller.m中的代码实现
- (void)viewDidLoad {
[super viewDidLoad];
self.listTableView.dataSource = self;
self.listTableView.delegate = self;
UIBarButtonItem * rightBarBtn = [[UIBarButtonItem alloc] initWithTitle:@"增加" style:(UIBarButtonItemStylePlain) target:self action:@selector(addVegetables)];
[self.navigationItem setRightBarButtonItem:rightBarBtn]
;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[VegetableManager sharedInstance] vegetables].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Vegetable * vegModel = [[[VegetableManager sharedInstance] vegetables] objectAtIndex:indexPath.row];
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleValue1) reuseIdentifier:@"cell"];
cell.textLabel.text = vegModel.name;
cell.detailTextLabel.text = [NSString stringWithFormat:@"¥%.2f",vegModel.price];
return cell;
}
-(void)addVegetables
{
// 生成提示框
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"增加蔬菜" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
_alertController = alertController;
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"蔬菜名";
textField.tag = 1;
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"菜价";
textField.tag = 2;
}];
UIAlertAction * confirmAction = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
NSArray * textFields = _alertController.textFields;
NSString * vegName = nil;
double vegPrice = 0;
for (UITextField * tf in textFields) {
if (tf.tag == 1) {
vegName = tf.text;
}else if (tf.tag == 2)
{
vegPrice = [tf.text doubleValue];
}
}
Vegetable * vegModel = [[Vegetable alloc] init];
vegModel.name = vegName;
vegModel.price = vegPrice;
[[VegetableManager sharedInstance] addvegetable:vegModel];
[_listTableView reloadData];
_alertController = nil;
}];
[alertController addAction:confirmAction];
UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:nil];
[alertController addAction:cancelAction];
[self presentViewController:alertController animated:YES completion:nil];
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
//- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{
//
//}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
}
- ( UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(11.0)){
if (@available(iOS 11.0, *)) {
UIContextualAction * addRowAction = [UIContextualAction contextualActionWithStyle:(UIContextualActionStyleNormal) title:@"加一块钱" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"操作提醒" message:@"确定要加1块钱吗?" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// NSLog(@"加一块钱");
Vegetable *vegModel = [[VegetableManager sharedInstance].vegetables objectAtIndex:indexPath.row];
[[VegetableManager sharedInstance] changePrice:vegModel.price + 1 Name:vegModel.name];
[self.listTableView reloadData];
}];
UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
[alertController addAction:action1];
[alertController addAction:action2];
//显示alertController
[self presentViewController:alertController animated:YES completion:nil];
}];
UIContextualAction *deleteRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"删除" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"操作提醒" message:@"确定要删除该记录吗?" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// NSLog(@"删除了这条记录");
Vegetable *vegModel = [[VegetableManager sharedInstance].vegetables objectAtIndex:indexPath.row];
[[VegetableManager sharedInstance] removeVegetableWihtName:vegModel.name];
[self.listTableView reloadData];
}];
UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}];
[alertController addAction:action1];
[alertController addAction:action2];
//显示alertController
[self presentViewController:alertController animated:YES completion:nil];
}];
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteRowAction,addRowAction]];
config.performsFirstActionWithFullSwipe = NO;
return config;
} else {
// Fallback on earlier versions
return nil;
}
}
@end
网友评论