【iOS】——知乎日报第五周总结

news/2024/7/20 21:21:00 标签: ios, cocoa, macos, FMDB

文章目录

  • 一、评论区展开与收缩
  • 二、FMDB库实现本地持久化
  • 三、点赞和收藏的持久化


一、评论区展开与收缩

有的评论没有被回复评论或者被回复评论过短,这时就不需要展开全文的按钮,所以首先计算被回复评论的文本高度,根据文本高度来决定是否隐藏展开全文的按钮。

CGSize constrainedSize = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
    NSDictionary *attributes = @{NSFontAttributeName: cell.replyLabel.font}; // label为要计算高度的UILabel控件
    CGRect textRect = [cell.replyLabel.text boundingRectWithSize:constrainedSize
                                         options:NSStringDrawingUsesLineFragmentOrigin
                                      attributes:attributes
                                         context:nil];
    CGFloat textHeight = CGRectGetHeight(textRect);
    if (textHeight > 100) {
        cell.foldButton.hidden = NO;
    } else {
        cell.foldButton.hidden = YES;
    }

要实现评论区的展开全文和收起,需要先实现评论区文本的自适应高度,接着我用数组来记录每个按钮的状态,如果为展开状态则为1,如果为收起状态则为0。通过数组中按钮的状态为按钮的selected属性做出选择并改变cell的高度。当我点击按钮时就改变该按钮在数组中的相应值。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0 && self.longComments != 0) {

        NSString* longStr = [self.discussModel.longCommentsArray[indexPath.row] content];
        NSString* longReplyStr = [self.discussModel.longCommentsArray[indexPath.row] reply_to][@"content"];
        CGSize constrainedSize = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font = [UIFont systemFontOfSize:18.0];
        NSDictionary *attributes = @{NSFontAttributeName: font}; // label为要计算高度的UILabel控件
        CGRect textRect = [longStr boundingRectWithSize:constrainedSize
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes
                                             context:nil];
        CGFloat textHeight = CGRectGetHeight(textRect);
        
        CGSize constrainedSize02 = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font02 = [UIFont systemFontOfSize:16.0];
        NSDictionary *attributes02 = @{NSFontAttributeName: font02}; // label为要计算高度的UILabel控件
        CGRect textRect02 = [longReplyStr boundingRectWithSize:constrainedSize02
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes02
                                             context:nil];
        CGFloat textHeight02 = CGRectGetHeight(textRect02);
        
        NSLog(@"长评论高度为:%f", textHeight);
        if ([self.discussModel.longButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            return textHeight + textHeight02 + 180;
        }
        return textHeight + 180;
    } else {
        NSString* shortStr = [self.discussModel.shortCommentsArray[indexPath.row] content];
        NSString* shortReplyStr = [self.discussModel.shortCommentsArray[indexPath.row] reply_to][@"content"];
        CGSize constrainedSize = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font = [UIFont systemFontOfSize:18.0];
        NSDictionary *attributes = @{NSFontAttributeName: font}; // label为要计算高度的UILabel控件
        CGRect textRect = [shortStr boundingRectWithSize:constrainedSize
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes
                                             context:nil];
        CGFloat textHeight = CGRectGetHeight(textRect);
        
        CGSize constrainedSize02 = CGSizeMake(WIDTH - 70, CGFLOAT_MAX); // labelWidth为UILabel的宽度,高度设置为无限大
        UIFont *font02 = [UIFont systemFontOfSize:16.0];
        NSDictionary *attributes02 = @{NSFontAttributeName: font02}; // label为要计算高度的UILabel控件
        CGRect textRect02 = [shortReplyStr boundingRectWithSize:constrainedSize02
                                             options:NSStringDrawingUsesLineFragmentOrigin
                                          attributes:attributes02
                                             context:nil];
        CGFloat textHeight02 = CGRectGetHeight(textRect02);
        
        NSLog(@"段评论高度为:%f", textHeight);
        if ([self.discussModel.shortButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            return textHeight + textHeight02 + 180;
        }
        return textHeight + 180;
    }  
}

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0 && self.longComments != 0) {
        if (indexPath.row == 0) {
            cell.commentsNumLabel.text = [NSString stringWithFormat:@"%ld条长评", self.longComments];
        }
        cell.foldButton.tag = indexPath.row * 2 + 1;
        if ([self.discussModel.longButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            cell.foldButton.selected = YES;
            cell.replyLabel.numberOfLines = 0;
        } else {
            cell.foldButton.selected = NO;
            cell.replyLabel.numberOfLines = 2;
        }
}else {
        
        cell.foldButton.tag = indexPath.row * 2;
        if ([self.discussModel.shortButtonSelectArray[indexPath.row] isEqualToString:@"1"]) {
            cell.foldButton.selected = YES;
            cell.replyLabel.numberOfLines = 0;
        } else {
            cell.foldButton.selected = NO;
            cell.replyLabel.numberOfLines = 2;
        }
- (void)pressFold:(UIButton*)button {
    DiscussCustomCell* cell = (DiscussCustomCell*)[[button superview] superview];
    if ([self.discussModel.longButtonSelectArray[(button.tag - 1) / 2] isEqualToString:@"1"]) {
        [self.discussModel.longButtonSelectArray replaceObjectAtIndex:((button.tag - 1) / 2) withObject:@"0"];
        [self.discussView.tableview reloadData];
    } else {
        [self.discussModel.longButtonSelectArray replaceObjectAtIndex:((button.tag - 1) / 2) withObject:@"1"];
        [self.discussView.tableview reloadData];
    }
    
    if ([self.discussModel.shortButtonSelectArray[button.tag / 2] isEqualToString:@"1"]) {
        [self.discussModel.shortButtonSelectArray replaceObjectAtIndex:(button.tag / 2) withObject:@"0"];
        [self.discussView.tableview reloadData];
    } else {
        [self.discussModel.shortButtonSelectArray replaceObjectAtIndex:(button.tag / 2) withObject:@"1"];
        [self.discussView.tableview reloadData];
    }
}

请添加图片描述

请添加图片描述

FMDB_137">二、FMDB库实现本地持久化

FMDB是iOS平台的SQLite数据库框架,以OC的方式封装了SQLite的C语言API。

FMDB_140">FMDB常用类:

FMDatabase:一个FMDatabase对象就代表一个单独的SQLite数据库用来执行SQL语句。
FMResultSet:使用FMDatabase执行查询后的结果集。
FMDatabaseQueue:用于在多线程中执行多个查询或更新,它是线程安全的。

FMDB_146">FMDB的简单使用:

要使用FMDB库首先需要通过CocoaPods来安装这个第三方库

pod 'FMDB'

安装完成之后就可以进行使用了。

创建数据库

//获取数据库文件的路径
    NSString* doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

        NSString *fileName = [doc stringByAppendingPathComponent:@"collectionData.sqlite"];
    //获得数据库
    self.collectionDatabase = [FMDatabase databaseWithPath:fileName];
    //打开数据库
    if ([self.collectionDatabase open]) {
        BOOL result = [self.collectionDatabase executeUpdate:@"CREATE TABLE IF NOT EXISTS collectionData (mainLabel text NOT NULL, nameLabel text NOT NULL, imageURL text NOT NULL, networkURL text NOT NULL, dateLabel text NOT NULL, nowLocation text NOT NULL, goodState text NOT NULL, collectionState text NOT NULL, id text NOT NULL);"];
        if (result) {
            NSLog(@"创表成功");
        } else {
            NSLog(@"创表失败");
        }
    }

数据库增加数据

//插入数据
- (void)insertData {
    if ([self.collectionDatabase open]) {
        NSString *string = @"GenShen";
        BOOL result = [self.collectionDatabase executeUpdate:@"INSERT INTO collectionData (mainLabel, nameLabel, imageURL, networkURL, dateLabel, nowLocation, goodState, collectionState, id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", string, string, string, string, string, string, string, string, string];
        if (!result) {
            NSLog(@"增加数据失败");
        }else{
            NSLog(@"增加数据成功");
        }
        [self.collectionDatabase close];
    }
}

数据库修改数据

//修改数据
- (void)updateData {
    if ([self.collectionDatabase open]) {
        NSString* sql = @"UPDATE collectionData SET id = ? WHERE nameLabel = ?";
        BOOL result = [self.collectionDatabase executeUpdate:sql, @"114514",@"GenShen"];
        if (!result) {
                    NSLog(@"数据修改失败");
                } else {
                    NSLog(@"数据修改成功");
                }
                [self.collectionDatabase close];
    }
}

数据库删除数据

//删除数据
- (void)deleteData {
    if ([self.collectionDatabase open]) {
        NSString* sql = @"delete from collectionData WHERE collectionState = ?";
        BOOL result = [self.collectionDatabase executeUpdate:sql, @"爱玩原神"];
        if (!result) {
                    NSLog(@"数据删除失败");
                } else {
                    NSLog(@"数据删除成功");
                }
                [self.collectionDatabase close];
    }
}

数据库查询数据

//查询数据
- (void)queryData {
    if ([self.collectionDatabase open]) {
        FMResultSet* resultSet = [self.collectionDatabase executeQuery:@"SELECT * FROM collectionData"];
        while ([resultSet next]) {
                    NSString *mainLabel = [resultSet stringForColumn:@"mainLabel"];
                    NSLog(@"mainLabel = %@",mainLabel);
                    NSString *nameLabel = [resultSet stringForColumn:@"nameLabel"];
                    NSLog(@"nameLabel = %@",nameLabel);
                    NSString *imageURL = [resultSet stringForColumn:@"imageURL"];
                    NSLog(@"imageURL = %@",imageURL);
                    NSString *networkURL = [resultSet stringForColumn:@"networkURL"];
                    NSLog(@"networkURL = %@",networkURL);
                    NSString *dateLabel = [resultSet stringForColumn:@"dateLabel"];
                    NSLog(@"dateLabel = %@",dateLabel);
                    NSString *nowLocation = [resultSet stringForColumn:@"nowLocation"];
                    NSLog(@"nowLocation = %@",nowLocation);
                    NSString *goodState = [resultSet stringForColumn:@"goodState"];
                    NSLog(@"goodState = %@",goodState);
                    NSString *collectionState = [resultSet stringForColumn:@"collectionState"];
                    NSLog(@"collectionState = %@",collectionState);
                    NSString *id = [resultSet stringForColumn:@"id"];
                    NSLog(@"id = %@",id);
                }
                [self.collectionDatabase close];
    }
}

三、点赞和收藏的持久化

要实现点赞和收藏的持久化就需要用到前面所提到的FMDB库进行操作。在需要用到数据库的部分进行数据库的创建和一些基本操作例如增删改查。以收藏持久化为例子,当点击点赞收藏按钮的时候,进入到数据库查询函数进行查询,如果找到就将该数据进行删除然后将按钮状态设置为未选中状态。如果没有找到该数据就进行添加然后将按钮状态设置为选中状态

- (void)pressCollect:(UIButton*)button {
    
        NSString* collectionIdStr = [NSString stringWithFormat:@"%ld", self.idStr];
        int flag = [self queryCollectionData];
        if (flag == 1) {
            self.mainWebView.collectButton.selected = NO;
            [self deleteCollectionData:collectionIdStr];
        } else {
            self.mainWebView.collectButton.selected = YES;
            [self insertCollectionData:self.mainLabel andUrl:self.imageUrl andStr:collectionIdStr];
        }
}


当滑动切换页面请求新闻额外信息时也需要先进行判断当前点赞和收藏的按钮状态

[[ExtraManager sharedSingleton] ExtraGetWithData:^(GetExtraModel * _Nullable extraModel) {
        dispatch_async(dispatch_get_main_queue(), ^{
            int flag = [self queryLikesData];
            int collectFlag = [self queryCollectionData];
            self.mainWebView.discussLabel.text = [NSString stringWithFormat:@"%ld", extraModel.comments];
            self.mainWebView.likeLabel.text = [NSString stringWithFormat:@"%ld", extraModel.popularity];
            self.longComments = extraModel.long_comments;
            self.shortComments = extraModel.short_comments;
            if (flag == 1) {
                self.mainWebView.likeButton.selected = YES;
                NSInteger likesNum = [self.mainWebView.likeLabel.text integerValue];
                likesNum++;
                self.mainWebView.likeLabel.text = [NSString stringWithFormat:@"%ld", likesNum];
                NSString* likesIdStr = [NSString stringWithFormat:@"%ld", self.idStr];
                [self insertLikesData:likesIdStr];
            } else {
                self.mainWebView.likeButton.selected = NO;
            }
            if (collectFlag == 1) {
                self.mainWebView.collectButton.selected = YES;
            } else {
                self.mainWebView.collectButton.selected = NO;
            }
            
            NSLog(@"额外信息获取成功");
        });
        } andError:^(NSError * _Nullable error) {
            NSLog(@"额外信息获取失败");
        } andIdStr:self.idStr];

收藏数据库部分代码如下:

//创建
- (void)databaseInit {
    NSString* likesDoc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSLog(@"%@", likesDoc);
        NSString * likesFileName = [likesDoc stringByAppendingPathComponent:@"likesData.sqlite"];
    self.likesDatabase = [FMDatabase databaseWithPath:likesFileName];
    if ([self.likesDatabase open]) {
            BOOL result = [self.likesDatabase executeUpdate:@"CREATE TABLE IF NOT EXISTS likesData (id text NOT NULL);"];
            if (result) {
                NSLog(@"创表成功");
            } else {
                NSLog(@"创表失败");
            }
        }
    
    NSString* collectionDoc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSLog(@"%@", collectionDoc);
        NSString * collectionFileName = [collectionDoc stringByAppendingPathComponent:@"collectionData02.sqlite"];
    self.collectionDatabase = [FMDatabase databaseWithPath:collectionFileName];
    if ([self.collectionDatabase open]) {
            BOOL result  = [self.collectionDatabase executeUpdate:@"CREATE TABLE IF NOT EXISTS collectionData (mainLabel text NOT NULL, imageURL text NOT NULL, id text NOT NULL);"];
            if (result) {
                NSLog(@"创表成功");
            } else {
                NSLog(@"创表失败");
            }
        }
    
}
//增加
- (void)insertCollectionData:(NSString *)mainLabel andUrl:(NSString *)imageURL andStr:(NSString*)string {
    if ([self.collectionDatabase open]) {
        BOOL result = [self.collectionDatabase executeUpdate:@"INSERT INTO collectionData (mainLabel, imageURL, id) VALUES (?, ?, ?);", mainLabel, imageURL,string];
        if (!result) {
            NSLog(@"增加收藏数据失败");
        }else{
            NSLog(@"增加收藏数据成功");
        }
    }
    [self.collectionDatabase close];
}
//删除
- (void)deleteCollectionData:(NSString*)string {
    if ([self.collectionDatabase open]) {
        NSString *sql = @"delete from collectionData WHERE id = ?";
        BOOL result = [self.collectionDatabase executeUpdate:sql, string];
        if (!result) {
            NSLog(@"删除收藏数据失败");
        }else{
            NSLog(@"删除收藏数据成功");
        }
    }
    [self.collectionDatabase close];
}

//查询
- (int)queryCollectionData {
    if ([self.collectionDatabase open]) {
        FMResultSet* collectionResultSet = [self.collectionDatabase executeQuery:@"SELECT * FROM collectionData"];
        int count = 0;
        while ([collectionResultSet next]) {
            NSString *sqlIdStr = [NSString stringWithFormat:@"%@", [collectionResultSet objectForColumn:@"id"]];
            NSInteger sqlId = [sqlIdStr integerValue];
            NSLog(@"第 %d 个收藏数据库数据:%ld", count++ ,sqlId);
            if (self.idStr == sqlId) {
                [self.collectionDatabase close];
                return 1;
            }
           
        }
    }
    [self.collectionDatabase close];
    return 0;
}

请添加图片描述

请添加图片描述


http://www.niftyadmin.cn/n/5195093.html

相关文章

qsort使用举例和qsort函数的模拟实现

qsort使用举例 qsort是C语言中的一个标准库函数,用于对数组或者其他数据结构中的元素进行排序。它的原型如下: void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 我们可以去官网搜来看一看:…

C语言 字符函数汇总,模拟实现各字符函数(炒鸡详细)

目录 求字符串长度 strlen 示例 模拟实现strlen 长度不受限制的字符串函数 strcpy 示例 模拟实现strcpy strcat 模拟实现strcat strcmp 示例 模拟实现strcmp 长度受限制的字符串函数介绍 strncpy 示例 模拟实现strncpy strncat 示例 模拟实现strncat s…

【华为OD机试高分必刷题目】洗衣服(JavaPythonC++贪心算法实现)

🚀你的旅程将在这里启航!本专栏所有题目均包含优质解题思路,每篇都用了Java&Python&C++分别解题,高质量解题代码,详细代码讲解,助你深入学习,高分通过! 文章目录 【华为OD机试高分必刷题目】洗衣服(Java&Python&C++贪心算法实现)题目描述解题思路Py…

【python基础】类详解:如何编写类、__init__()、修改实例属性、类存储到模块并导入、py标准库、编写类的约定

文章目录 一. 创建和使用类1. 创建Dog类1.1. 构造方法:1.2. 形参self(类比java的this):1.3. 属性(类比java的成员变量): 2. 根据类创建实例2.1. 创建实例2.2. 访问属性2.3. 调用方法2.4. 创建多…

【数据结构(二)】单链表(3)

文章目录 1. 链表介绍2. 单链表应用实例2.1. 顺序添加方式2.1.1. 思路分析2.1.2. 代码实现 2.2. 按照编号顺序添加方式2.2.1. 思路分析2.2.2. 代码实现 3. 单链表节点的修改3.1. 思路分析3.2. 代码实现 4. 单链表节点的删除4.1. 思路分析4.2. 代码实现 5. 单链表常见面试题5.1.…

基于SSM的电影小说网站设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

Shaderlab的组成部分SubShader

文档 渲染标签 渲染状态 渲染通道 Subshader 一个shader文件至少有一个subshader;多个subshader的顺序一般按照效果好到差的顺序编写显示物体的时候,设备从多个subshader中,按从前到后的顺序找到第一个符合的subshader进行执行 Subshader组成 渲染标…

18. Spring类型转换之ConversionService

简介 前面我们讲了PropertyEditor,是jdk提供的类型转换,spring也有自己的类型转换器,比PropertyEditor稍微强大一点 快速使用 public class User {private String name;public String getName() {return name;}public void setName(String…