需求非常简单,参考新闻详情内图文穿插布局,从服务器获取数据后进行排版。
抓取如头条新闻内容详情报文,是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);
}