[iOS]知乎日报第四周总结-唐妞不等式秒了之没写完不等于不能发博客

本文讲述了在iOS开发中如何处理自适应高度cell,包括使用计算UILabel高度的方法和通过Masonry实现动态布局。同时介绍了FMDB库的基本使用,如数据的CRUD操作和数据库路径管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[iOS]知乎日报第四周总结-唐妞不等式秒了之没写完不等于不能发博客

小结

本周依旧很摆
但这不耽误我写博客

还差一些部分这个知乎日报就结束了
被自适应高度cell为难了好久

自适应高度cell

法一:写个方法计算label高度

代码来源和具体方法

-(CGSize)ZFYtextHeightFromTextString:(NSString *)text width:(CGFloat)textWidth fontSize:(CGFloat)size{
    //计算 label需要的宽度和高度
    NSDictionary *dict = @{NSFontAttributeName:[UIFont systemFontOfSize:size]};
    CGRect rect = [text boundingRectWithSize:CGSizeMake(textWidth, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];
    
     CGSize size1 = [text sizeWithAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:size]}];
    
    return CGSizeMake(size1.width, rect.size.height);
}

法二:通过Masonry布局实现

通过masonry的约束来撑开cell的高度是很简单实用的方法
这里就不做背景介绍了
简单讲下步骤
然后是需要注意的一些点

步骤

要使用 Masonry 实现自适应高度,你可以借助 UITableView 的 estimatedRowHeight 和 rowHeight 属性,以及 Masonry 的自动布局功能。以下是实现步骤:

  1. 首先,确保你的 UITableViewCell 中的子视图使用了 Masonry 进行自动布局。

  2. 在 UITableView 的数据源方法中,设置 estimatedRowHeight 和 rowHeight 属性。estimatedRowHeight 用于估算行高,rowHeight 用于设置具体的行高。

tableView.estimatedRowHeight = 100; // 估算的行高
tableView.rowHeight = UITableViewAutomaticDimension; // 设置为自动计算高度
  1. 在 UITableViewCell 的 - (void)awakeFromNib 方法中,添加子视图并设置 Masonry 约束。
- (void)awakeFromNib {
    [super awakeFromNib];
    // 添加子视图并设置Masonry约束
    [self.contentView addSubview:self.titleLabel];
    [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView.mas_top).offset(8);
        make.left.equalTo(self.contentView.mas_left).offset(8);
        make.right.equalTo(self.contentView.mas_right).offset(-8);
    }];
    // 添加其他子视图并设置Masonry约束
}

通过上述步骤,你就可以使用 Masonry 实现自适应高度。当内容发生变化时,UITableView 会根据实际内容重新计算高度,从而实现动态高度的 UITableViewCell。

注意
  1. 使用masonry约束后 不要再使用下面的方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
  1. 将masonry布局放在以下方法中,才能在调用时正确撑开cell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
  1. 想要撑开cell必须保证你的布局内包括对contentView的top与bottm都要有所约束
[self.imagebtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.contentView).offset(20);
        make.top.equalTo(self.contentView).offset(10);
        make.size.mas_equalTo(30);
    }];
    
    [self.namelabel mas_makeConstraints:^(MASConstraintMaker *make) {
        //由于要自适应的cell,所以不用宽高约束
        make.left.mas_equalTo(self.imagebtn.mas_right).mas_offset(10);
        make.top.equalTo(self.imagebtn.mas_top).offset(-5);
        make.width.mas_offset(300);
    }];
 
    [self.label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(self.imagebtn.mas_right).mas_offset(10);
        make.top.equalTo(self.namelabel.mas_bottom).offset(5);
        make.right.mas_equalTo(-20);
        make.width.mas_offset(300);
        make.height.mas_lessThanOrEqualTo(self.contentView.bounds.size.height);
    }];
 
     [self.sublabel mas_makeConstraints:^(MASConstraintMaker *make) {
         make.left.mas_equalTo(self.imagebtn.mas_right).mas_offset(10);
         make.top.equalTo(self.label.mas_bottom).offset(5);
         make.width.mas_offset(300);
     }];
    [self.timelabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(self.imagebtn.mas_right).mas_offset(10);
        make.top.equalTo(self.sublabel.mas_bottom).offset(10);
        make.bottom.equalTo(self.contentView.mas_bottom).offset(-20);
        make.width.mas_offset(300);
    }];
    [self.commentbtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.sublabel.mas_bottom).offset(5);
        make.bottom.equalTo(self.contentView.mas_bottom).offset(-20);
        make.right.mas_equalTo(-20);
        make.size.mas_equalTo(20);
    }];
    [self.likebtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.sublabel.mas_bottom).offset(5);
        make.bottom.equalTo(self.contentView.mas_bottom).offset(-20);
        make.right.mas_equalTo(self.commentbtn.mas_left).mas_offset(-30);
        make.size.mas_equalTo(20);
    }];

可折叠cell

这个要多讲吗
主要不是使用 是复用的问题啦
但是咱们还是过一遍叭

使用

除去和普通tableView的超初始化以外 还有一点要准备

foldtableView.userInteractionEnabled = YES;

当然 展开以后肯定也需要重新设置大小

 _foldtableView.frame = CGRectMake(210, 140, 140, 30 * _foldarrayData.count);

然后还有这个也是必须的 让我们能展开这个cell

cell.userInteractionEnabled = YES;

复用

tableView的复用机制:注册的一类cell中若有多个cell,那么在后续刷新的时候后面的cell会利用上面的cell的视图及其数据,若两个cell中需要显示的视图不完全一样,那么就会出现下方的cell刷新出本来不需要的视图
解决方法也简单:

//例如:
if (cell == nil) {
	cell = [[CommentTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"14"];
} else {             
    //删除cell的所有子视图
	[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
	//重新初始化,将需要的UI控件重新添加到视图上,但没有之前cell的数据
	cell = [[CommentTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"14"];            
}

FMDB

好的 让我们来看看FMDB
这个也需要通过pod安装 这里也不赘述了

看看使用意义

意义

  1. FMDB是iOS平台的SQLite数据库框架
  2. FMDB以OC的方式封装了SQLite的C语言API
  3. 使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
  4. 对比苹果自带的Core Data框架,更加轻量级和灵活
  5. 提供了多线程安全的数据库操作方法,有效地防止数据混乱

核心

FMDB有三个主要的类

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

步骤

这里有篇很详细的
还是过一遍
顺便水一点字数

获取路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSLog(@"%@", doc);
    NSString *fileName = [doc stringByAppendingPathComponent:@"collectionData.sqlite"];
获取打开
FMDatabase *collectionDatabase = [FMDatabase databaseWithPath:fileName];
 BOOL executeUpdate = [dataBase executeUpdate:@"CREATE TABLE IF NOT EXISTS t_collect (id text NOT NULL);"];
                    if (executeUpdate) {
                        NSLog(@"创建表成功");
                    } else {
                        NSLog(@"创建表失败");
                    }

通常对数据库的操作,我们一般称为CURD,即对表进行创建(Create)、更新(Update)、读取(Read)和删除(Delete)操作。

插入数据
//插入数据
- (void)insertData {
    if ([self.collectionDatabase open]) {
        NSString *string = @"hi world";
        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, @"1", @"hi world"];
        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, @"xixixixi"];
        if (!result) {
            NSLog(@"数据删除失败");
        } else {
            NSLog(@"数据删除成功");
        }
        [self.collectionDatabase close];
    }
}
查找数据
// 查询数据
- (void)queryData {
    if ([self.collectionDatabase open]) {
        // 1.执行查询语句
        FMResultSet *resultSet = [self.collectionDatabase executeQuery:@"SELECT * FROM collectionData"];
        // 2.遍历结果
        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];
    }
}

好了新手教程就到这里了
加油吧勇士!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值