iOS图文:仿新闻内容简单图文混排

795 阅读2分钟

需求非常简单,参考新闻详情内图文穿插布局,从服务器获取数据后进行排版。

抓取如头条新闻内容详情报文,是xml结构的数组。

现在数据被简单定义为一个字典数组,xml解析比较麻烦,以后写。

为了减少工作量,直接用iOS系统提供的AutoLayout布局。

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.contentView addSubview:self.bodyView];
}

-(UIView *)contentView{
    if(!_contentView){
        _contentView=[UIView new];
    }
    return _contentView;
}

- (UIView *)bodyView {
    if(!_bodyView){
        _bodyView=[UIView new];
    }
    return _bodyView;
}

参考代码如下:

- (void)setBodyTextWithContent:(NSArray *)contentArr {
    UIView *lastDockView = self.bodyView;
    for (NSUInteger i=0; i<contentArr.count; i++) {
        NSString *type = [contentArr[i] objectForKey:@"type"];
        if ([type isEqualToString:@"text"]) {
            
            NSString *text = [contentArr[i] objectForKey:@"content"];
            
            NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:text];
            NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
            paragraphStyle.lineSpacing = 8.0; // 设置行间距
            paragraphStyle.alignment = NSTextAlignmentJustified; //设置两端对齐显示
            [attributedStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedStr.length)];
            
            UILabel *contentLabel = [[UILabel alloc] init];
            contentLabel.numberOfLines=0;
            contentLabel.font=[UIFont systemFontOfSize:15];
            contentLabel.textColor=[UIColor blackColor];
            contentLabel.textAlignment=NSTextAlignmentLeft;
            contentLabel.lineBreakMode = NSLineBreakByWordWrapping;
            contentLabel.preferredMaxLayoutWidth = kScreenWidth-30;
            contentLabel.attributedText = attributedStr;
            //添加到视图
            [self.bodyView addSubview:contentLabel];
            //添加约束 注意分情况讨论,分为首次添加和后续添加
            
            if ([lastDockView isEqual:self.bodyView]) {
                //第一次添加
                [contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(self.bodyView).offset(15);
                    make.right.equalTo(self.bodyView).offset(-15);
                    make.top.equalTo(self.bodyView).offset(12);
                }];
            } else {
                //后续添加
                [contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(self.bodyView).offset(15);
                    make.right.equalTo(self.bodyView).offset(-15);
                    make.top.equalTo(lastDockView.mas_bottom).offset(12);
                }];
            }
            lastDockView = contentLabel;
            
        } else if ([type isEqualToString:@"img"]){
            
            UIImageView *imgcell=[UIImageView new];
            imgcell.contentMode = UIViewContentModeScaleAspectFit;
            
            [imgcell sd_setImageWithURL:[NSURL URLWithString:[contentArr[i] objectForKey:@"url"]] placeholderImage:[UIImage imageNamed:@"placehoder"] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
                CGFloat imgW = 0;
                CGFloat imgH = 0;
                CGFloat tmpW = image.size.width;
                CGFloat tmpH = image.size.height;
                if (tmpW > kScreenWidth-30) {
                    imgW = kScreenWidth-30;
                    imgH = (kScreenWidth-30)*tmpH/tmpW;
                } else {
                    imgW = tmpW;
                    imgH = tmpH;
                }
                
                [imgcell mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.height.mas_equalTo(imgH);
                }];
                
                [self relayoutContentView];
            }];
            [self.bodyView addSubview:imgcell];
            
            if ([lastDockView isEqual:self.bodyView]) {
                //第一次添加
                [imgcell mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(self.bodyView).offset(15);
                    make.right.equalTo(self.bodyView).offset(-15);
                    make.top.equalTo(self.bodyView).offset(12);
                    make.width.mas_equalTo(kScreenWidth - 30);
                }];
            } else {
                //后续添加
                [imgcell mas_makeConstraints:^(MASConstraintMaker *make) {
                    make.left.equalTo(self.bodyView).offset(15);
                    make.right.equalTo(self.bodyView).offset(-15);
                    make.top.equalTo(lastDockView.mas_bottom).offset(12);
                    make.width.mas_equalTo(kScreenWidth - 30);
                }];
            }
            lastDockView = imgcell;
        } else {
            
            
        }
    }
    
    [self.bodyView mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.left.equalTo(self.contentView);
        make.right.equalTo(self.contentView);
        make.top.equalTo(self.contentView);
        make.bottom.equalTo(lastDockView.mas_bottom);
    }];
}



注意:如果数据没有提供图片宽高,需要在sd_web的回调中获取,这时候必须重新刷新布局,否则图片占位默认会被拉的很长,具体图片设置多大根据实际需求来。

图片宽高获取方法记录如下:

iOS开发 - 根据图片URL获取图片的尺寸(宽高)

这边提供刷新layout代码参考:

- (void)relayoutContentView {
    [self.view layoutIfNeeded];
    self.contentView.frame=CGRectMake(0, 0, kScreenWidth, self.bodyView.maxY);
}