Quantcast
Viewing all articles
Browse latest Browse all 5930

Masonry 布局 cell高度适应的一种方案(实现类似朋友圈简单布局)

—更好的阅读体验请点击原文链接

前言: 我模仿的是微博的布局所以也就没有 评论动态刷新cell.

  1. 什么人群适合看?

    好奇Masonry使用的, 听过没用过, 没有深入的接触过的 可以看.

  2. 为什么要写?

    很多文章都是这个原因 1 备忘 2 给需要的人 -.-

  3. 这篇可以了解哪些?

    Masonry + HYBMasonryAutoCellHeight + TTTAttributedLabel + 话题正则 + 表情正则 + 链接 同时感谢作者开源
    这里图片浏览器使用的 SDPhotoBrowser

  4. 使用方便吗?

    使用很方便, 不需要通过文本的宽度计算高度来自适应label了, 使用Masonry 在iOS10 貌似没有出现因为像素点原因, 而显示不完全的问题~

Image may be NSFW.
Clik here to view.
我用类似于微博界面的样式进行测试的 so最帅的头像就是我的微博啦

Image may be NSFW.
Clik here to view.
我用类似于微博界面的样式进行测试的 so最帅的头像就是我的微博啦

Image may be NSFW.
Clik here to view.
我用类似于微博界面的样式进行测试的 so最帅的头像就是我的微博啦

下面进入正题代码的实现~

布局cell上的子控件

        // Masonry布局
        // 头像
        [_headerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
            // 进行约束设置
            make.top.left.equalTo(self.contentView).with.offset(SPACE);
            make.width.height.mas_equalTo(33);
        }];
        // 昵称
        // 文本内容要显示多长
        _labelName.preferredMaxLayoutWidth = SCREEN_W - 63;
        _labelName.numberOfLines = 0;
        [_labelName mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.contentView).with.offset(SPACE);
            make.left.equalTo(self.headerImageView.mas_right).with.offset(SPACE);
            make.right.equalTo(self.contentView).with.offset(-SPACE);
        }];
        // 时间
        _labelTime.preferredMaxLayoutWidth = SCREEN_W - 63;
        _labelTime.numberOfLines = 0;
        [_labelTime mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.labelName.mas_bottom).with.offset(SPACE); // 空隙 为 10(SPACE)
            make.left.right.equalTo(self.labelName);
        }];
        // 发布的内容
        // 视图是多宽的 进行相应的设置
        self.labelText.preferredMaxLayoutWidth = SCREEN_W - 63;
        _labelText.numberOfLines = 0;
        [_labelText mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.labelTime.mas_bottom).with.offset(SPACE);
            make.left.right.mas_equalTo(self.labelTime);
        }];
        // 自动检测链接
        _labelText.enabledTextCheckingTypes = NSTextCheckingTypeLink;
        // 图片浏览器
        [_photosGroup mas_makeConstraints:^(MASConstraintMaker *make) {
            //
            make.top.equalTo(self.labelText.mas_bottom).with.offset(SPACE);
            make.left.equalTo(self.labelText);
            make.width.mas_equalTo(SCREEN_W - 63);
        }];

方法赋值 赋值 - 并且更新需要更新的布局

#pragma mark - 赋值
- (void)configCellWithModel:(CommonModel *)model user:(User *)userModel
{
    // 头像
    [_headerImageView sd_setImageWithURL:[NSURL URLWithString:userModel.profile_image_url] placeholderImage:nil];
    _labelName.text = [NSString stringWithFormat:@"%@ %@", userModel.name, @"我测试cell的高度是否准确, 我测试cell的高度是否准确"];
    _labelTime.text = [NSString stringWithFormat:@"%@ %@", model.created_at, @"我测试cell的高度是否准确, 我测试cell的高度是否准确"];;
    // 发布的内容
    _labelText.text = model.text;
    // 计算Photo的height
    // 这里用到了类似朋友圈的九宫格布局所以我进行了相应的计算
    CGFloat pg_Height = 0.0;
    if (model.pic_urls.count > 1 && model.pic_urls.count <= 3) {
        pg_Height = (SCREEN_W - 73) / 3 + 5;
    }else if(model.pic_urls.count > 3 && model.pic_urls.count <= 6)
    {
        pg_Height = (SCREEN_W - 73) / 3 * 2 + 10;
    }else if (model.pic_urls.count > 6 && model.pic_urls.count <= 9)
    {
        pg_Height = (SCREEN_W - 73) + 15;
    }else if (model.pic_urls.count == 1)
    {
        // 单张图片 为 4/7
        pg_Height = (SCREEN_W - 63) * 4 / 7 + 5;
    }
    else
    {
        pg_Height = 0.0;
    }
    // 同时九宫格进行更新约束
    [_photosGroup mas_updateConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(pg_Height);
    }];
}

在返回cell高度的方法中

#pragma mark - 返回 Cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CommonModel *model = self.dataArray[indexPath.row];
    User *user = self.userArray[indexPath.row];
    CGFloat cellHeight = [CommonTableViewCell hyb_heightForTableView:tableView config:^(UITableViewCell *sourceCell) {
        //
        CommonTableViewCell *cell = (CommonTableViewCell *)sourceCell;
        // 进行模型方法赋值-传进cell
        [cell configCellWithModel:model user:user];
    } cache:^NSDictionary *{
        return @{kHYBCacheUniqueKey: [NSString stringWithFormat:@"%@", model.id],
                 kHYBCacheStateKey : @"",
                 kHYBRecalculateForStateKey : @(NO) // 标识不用重新更新
                 };
    }];
    return cellHeight;
}

除去以上这些你可能还好奇 话题+表情+链接如何实现识别可点击的
写一个工具类

// .h
/// 话题正则 例如 #夏天帅不帅#
+ (NSRegularExpression *)regexTopic;

/// 表情正则 例如 [偷笑]
+ (NSRegularExpression *)regexEmoticon;
// .m
+ (NSRegularExpression *)regexTopic {
    static NSRegularExpression *regex;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        regex = [NSRegularExpression regularExpressionWithPattern:@"#[^@#]+?#" options:kNilOptions error:NULL];
    });
    return regex;
}

+ (NSRegularExpression *)regexEmoticon {
    static NSRegularExpression *regex;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        regex = [NSRegularExpression regularExpressionWithPattern:@"\\[[^ \\[\\]]+?\\]" options:kNilOptions error:NULL];
    });
    return regex;
}

然后在cell中进行使用检测文字

    // 话题检测
    NSArray *results = [[XTWBStatusHelper regexTopic] matchesInString:model.text options:0 range:NSMakeRange(0, model.text.length)];
    for (NSTextCheckingResult *result in results) {
        // 话题范围
        NSLog(@"range === %@", NSStringFromRange(result.range));
        [_labelText addLinkWithTextCheckingResult:result];
    }
    // 表情检测
    NSArray *results1 = [[XTWBStatusHelper regexEmoticon] matchesInString:model.text options:0 range:NSMakeRange(0, model.text.length)];
    for (NSTextCheckingResult *result in results1) {
        // 表情范围
        NSLog(@"range === %@", NSStringFromRange(result.range));
        [_labelText addLinkWithTextCheckingResult:result];
    }

TTTAttributedLabel的简单使用 — 点击了话题和链接 – 签订协议 指定代理人 实现协议方法

/// 点击链接的方法
- (void)attributedLabel:(TTTAttributedLabel *)label
   didSelectLinkWithURL:(NSURL *)url
{
    NSLog(@"被点击的url === %@", url);
}

/// 点击长按数据
- (void)attributedLabel:(TTTAttributedLabel *)label
  didSelectLinkWithDate:(NSDate *)date
{

}

/// 点击文本链接
- (void)attributedLabel:(TTTAttributedLabel *)label
didSelectLinkWithTextCheckingResult:(NSTextCheckingResult *)result
{
    NSLog(@"被点击的话题 === %@", NSStringFromRange(result.range))

}
/// 长按链接的方法
- (void)attributedLabel:(TTTAttributedLabel *)label
didLongPressLinkWithURL:(NSURL *)url
                atPoint:(CGPoint)point
{
    NSLog(@"被长按的url === %@", url);
}
/// 可以长按的文本
- (void)attributedLabel:(TTTAttributedLabel *)label
didLongPressLinkWithTextCheckingResult:(NSTextCheckingResult *)result
                atPoint:(CGPoint)point
{
    NSLog(@"被长按的话题 === %@", NSStringFromRange(result.range))
}

Image may be NSFW.
Clik here to view.
检测结果打印

总结: Masonry对cell的处理 我的逻辑是这样的, 对你有帮助点个喜欢/关注, 如果您有更好的方案, 请与我交流, 谢谢~.

疑问: 为什么简书Markdown不支持html标签

文/ 夏天然后

End

我的微博-点我@夏天是个大人了 || QQ群: 498143780 进群与我一起玩耍啊
最近还写了一些比较实用的文章 比如:
1. 如何把自己写的库添加Cocoapods支持
2. Hexo + GitHub 建站最详细教程 - 程序员还是写作爱好者都可以拥有这样一个个人站
3. 关于推送的文

作者:sinat_30162391 发表于2016/9/25 22:54:39 原文链接
阅读:171 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles