类似微博中的图片布局
类似这个效果,我们先分析一下界面,首先顶部和底部是不变的,所以我们采用xib的方式创建,如下
然后是中间的图片内容 因为中间的图片的个数不确定所以我们采用代码的方式创建出来,我们的构思是这样的当图片只有=一张的时候我们让图片的宽度为屏幕的宽度,当我图片为多张的时候我们平分这个屏幕的宽度,但是最多能放三张代码如下,
#import "PhotoView.h"
#import "UIImageView+WebCache.h"
#import "SDPhotoBrowser.h"
#define k_ScreenWidth ([UIScreen mainScreen].bounds.size.width)
#define k_ScreenHeight ([UIScreen mainScreen].bounds.size.height)
@interface PhotoView ()<SDPhotoBrowserDelegate>
@end
@implementation PhotoView
- (void)setImagesUrlStr:(NSArray *)imagesUrlStr
{
_imagesUrlStr = imagesUrlStr;
if (imagesUrlStr.count == 1) {
UIImageView * imageView = [[UIImageView alloc] init];
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)]];
[imageView sd_setImageWithURL:[NSURL URLWithString:imagesUrlStr[0]] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
imageView.tag = 100 ;
imageView.image = image;
CGSize size = CGSizeMake(k_ScreenWidth,(k_ScreenWidth * image.size.height )/image.size.width);
imageView.frame = CGRectMake(0, 0, size.width,200);
}];
imageView.contentMode = UIViewContentModeScaleToFill;
[self addSubview:imageView];
}else if(imagesUrlStr.count < 4){
for (int i=0; i<imagesUrlStr.count; i++) {
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(([UIScreen mainScreen].bounds.size.width) /(imagesUrlStr.count) * i, 0, ([UIScreen mainScreen].bounds.size.width) /(imagesUrlStr.count), 200)];
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)]];
[imageView sd_setImageWithURL:[NSURL URLWithString:[imagesUrlStr objectAtIndex:i]]];
imageView.tag = 100 + i;
imageView.contentMode = UIViewContentModeScaleToFill;
[self addSubview:imageView];
}
}else {
for (int i=0; i<imagesUrlStr.count; i++) {
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake((k_ScreenWidth /3) * (i%3), 150 *(i/3), k_ScreenWidth/3, 150)];
imageView.userInteractionEnabled = YES;
imageView.contentMode = UIViewContentModeScaleToFill;
[imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)]];
[imageView sd_setImageWithURL:[NSURL URLWithString:[imagesUrlStr objectAtIndex:i]]];
imageView.tag = 100 + i;
[self addSubview:imageView];
}
}
}
- (void)tapAction:(UITapGestureRecognizer*)tap
{
SDPhotoBrowser *photoBrowser = [SDPhotoBrowser new];
photoBrowser.delegate = self;
photoBrowser.currentImageIndex = tap.view.tag - 100 ;
photoBrowser.imageCount = self.imagesUrlStr.count;
photoBrowser.sourceImagesContainerView = self;
[photoBrowser show];
}
- (NSURL *)photoBrowser:(SDPhotoBrowser *)browser highQualityImageURLForIndex:(NSInteger)index
{
NSString *urlString = self.imagesUrlStr[index];
return [NSURL URLWithString:urlString];
}
- (UIImage *)photoBrowser:(SDPhotoBrowser *)browser placeholderImageForIndex:(NSInteger)index
{
UIImageView *imageView = [self viewWithTag:100 + index];
return imageView.image;
}
@end
如此这样就能实现如最上图所示的显示效果,但是还得防止cell的复用以及高度的计算。
为了防止cell的重用带来的重叠问题我们先来看cell的源码。
//
// TableViewCell.m
// 仿微博
//
// Created by zyyt on 16/7/20.
// Copyright © 2016年 sjb. All rights reserved.
//
#import "TableViewCell.h"
#import "PhotoView.h"
#import "PhotoModel.h"
#import "UIImageView+WebCache.h"
#import "UIImage+Circle.h"
@interface TableViewCell ()
//中间的图片
@property (nonatomic,weak)PhotoView * pictureView;
//头像
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
//用户名
@property (weak, nonatomic) IBOutlet UILabel *userNameLabel;
//时间
@property (weak, nonatomic) IBOutlet UILabel *creatDateLabel;
//文本内容
@property (weak, nonatomic) IBOutlet UILabel *contentTextLabel;
//顶
@property (weak, nonatomic) IBOutlet UIButton *praiseBtn;
//踩
@property (weak, nonatomic) IBOutlet UIButton *tireSomeBtn;
//分享
@property (weak, nonatomic) IBOutlet UIButton *shareBtn;
//收藏
@property (weak, nonatomic) IBOutlet UIButton *collectionBtn;
@end
@implementation TableViewCell
#pragma mark - 懒加载
- (PhotoView *)pictureView
{
if (_pictureView == nil) {
PhotoView * view = [[PhotoView alloc] init];
[self.contentView addSubview:view];
self.pictureView = view;
}
return _pictureView;
}
//赋值
- (void)setPhoto:(PhotoModel *)photo
{
_photo = photo;
self.userNameLabel.text = photo.userName;
self.creatDateLabel.text = photo.createDateStr;
self.contentTextLabel.text = photo.message;
[self.iconView sd_setImageWithURL:[NSURL URLWithString:photo.photo]completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
self.iconView.image = [image circleImage];
}];
/*
Sends to each object in the array the message identified by a given selector, starting with the first object and continuing through the array to the last object.
A selector that identifies the message to send to the objects in the array. The method must not take any arguments, and must not have the side effect of modifying the receiving array.
Parameters
aSelector
A selector that identifies the message to send to the objects in the array. The method must not take any arguments, and must not have the side effect of modifying the receiving array.
*/
if (photo.messageSmallPics.count > 0) {
//清除原有的子控件
[self.pictureView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)] ;
//设置frame
self.pictureView.frame = photo.pictureF;
self.pictureView.imagesUrlStr = photo.messageSmallPics;
//有图片时就显示pictureView
self.pictureView.hidden = NO;
}else{
//没有图片时就隐藏pictureView
self.pictureView.hidden = YES;
}
}
- (IBAction)praiseAction:(UIButton*)sender {
NSLog(@"%s",__func__);
}
- (IBAction)tireSomeAction:(UIButton*)sender {
NSLog(@"%s",__func__);
}
- (IBAction)shareAction:(UIButton *)sender {
NSLog(@"%s",__func__);
}
- (IBAction)collectionAction:(id)sender {
NSLog(@"%s",__func__);
}
@end
[self.pictureView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)] ;这句代码是每次赋值之前把pictureview的子控件清楚,如果pictureVie中还有其它类型的控件我们要判断,因为这里没有其它的控件我们就直接清除了所有的子控件。
下面我们来看计算cell高度的代码,为了方便代码的书写我们把计算cell的高度放在model里,model的代码书写如下,
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface PhotoModel : NSObject
@property (nonatomic,copy)NSString * userName;
@property (nonatomic,copy)NSString * photo;
@property (nonatomic,copy)NSString * message;
@property (nonatomic,copy)NSString * createDateStr;
@property (nonatomic,copy)NSArray * messageSmallPics;
//辅助特点
@property (nonatomic,assign)CGFloat cellHeight;
@property (nonatomic,assign,readonly)CGRect pictureF;
@end
------------------------------------------分割线-------------------------------------
//
// PhotoModel.m
// 仿微博
//
// Created by zyyt on 16/7/20.
// Copyright © 2016年 sjb. All rights reserved.
//
#import "PhotoModel.h"
#define cellMargin 10
@implementation PhotoModel
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
}
- (CGFloat)cellHeight
{
if (_cellHeight == 0) {
CGFloat top = 40 + cellMargin;
CGFloat contextHeight = [self.message boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 20, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil].size.height;
CGFloat middleHeight = cellMargin;
CGFloat imagesHeight = 0;
if (_messageSmallPics.count == 0) {
}else{
if (_messageSmallPics.count == 1) {
imagesHeight += 200;
_pictureF = CGRectMake(0, middleHeight + contextHeight + top, [UIScreen mainScreen].bounds.size.width, imagesHeight);
}else if (_messageSmallPics.count < 4){
imagesHeight += 200;
_pictureF = CGRectMake(0, middleHeight + contextHeight + top, [UIScreen mainScreen].bounds.size.width, imagesHeight);
}else if (_messageSmallPics.count < 7){
imagesHeight += 300;
_pictureF = CGRectMake(0, middleHeight + contextHeight + top, [UIScreen mainScreen].bounds.size.width, imagesHeight);
}else{
imagesHeight += 450;
_pictureF = CGRectMake(0, middleHeight + contextHeight + top, [UIScreen mainScreen].bounds.size.width, imagesHeight);
}
}
CGFloat bottomToolBarHeight = 40;
_cellHeight = top + contextHeight + middleHeight + imagesHeight + bottomToolBarHeight;
}
return _cellHeight;
}
@end
----------------------------分割线-------------------------
如上面的代码所示我们可以看到我们在model里直接得到了cell的高度和pictureView的frame
到此基本就实现了最上图的效果,下面是控制器的代码
//
// ViewController.m
// 仿微博
//
// Created by zyyt on 16/7/20.
// Copyright © 2016年 sjb. All rights reserved.
//
#import "ViewController.h"
#import "TableViewCell.h"
#import "PhotoModel.h"
@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,strong)UITableView * tableView;
@property (nonatomic,strong)NSMutableArray * dataSouce;
@end
static NSString * const cellID = @"Cell";
@implementation ViewController
- (NSMutableArray *)dataSouce
{
if (_dataSouce == nil) {
_dataSouce = [NSMutableArray array];
}
return _dataSouce;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupTableview];
[self requestData];
}
- (void)requestData
{
//把接送数据加载为字符串
NSString * str = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"] encoding:NSUTF8StringEncoding error:nil];
//把字符串转化为二进制流
NSData * data = [[NSData alloc] initWithData:[str dataUsingEncoding:NSUTF8StringEncoding]];
//解析二进制流
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
//NSLog(@"%@",);
//把字典转为模型
for (int i=0; i<[dic[@"data"][@"rows"] count]; i++) {
NSDictionary * dict =dic[@"data"][@"rows"][i];
PhotoModel * model = [[PhotoModel alloc] init];
[model setValuesForKeysWithDictionary:dict];
[self.dataSouce addObject:model];
}
[self.dataSouce addObjectsFromArray:self.dataSouce];
[self.dataSouce addObjectsFromArray:self.dataSouce];
[self.dataSouce addObjectsFromArray:self.dataSouce];
[self.tableView reloadData];
}
- (void)setupTableview
{
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([TableViewCell class]) bundle:nil] forCellReuseIdentifier:cellID];
[self.view addSubview:self.tableView];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataSouce.count;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellID];
cell.photo = [self.dataSouce objectAtIndex:indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
PhotoModel * model = [self.dataSouce objectAtIndex:indexPath.row];
return model.cellHeight;
}
@end
到此全部集成