ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 一效果 如果直接设置会有拉伸等等的状况,这里主要介绍图片显示的一些细节 ![](https://box.kancloud.cn/2016-01-20_569f1d999a2c9.jpg) ## 二:代码 代码实现其实很简单,微博当中用了一个photos来存放九宫格这些图片,然后用了一个photo类来做每个photo,并且在上面显示gif等的样式,很多很多小技巧,直接上代码 九宫格根据行列设置等算法,不难 ~~~ #import "HWStatusPhotosView.h" #import "HWPhoto.h" #import "HWStatusPhotoView.h" #define HWStatusPhotoWH 70 #define HWStatusPhotoMargin 10 #define HWStatusPhotoMaxCol(count) ((count==4)?2:3) @implementation HWStatusPhotosView // 9 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { } return self; } - (void)setPhotos:(NSArray *)photos { _photos = photos; int photosCount = photos.count; // 创建足够数量的图片控件 // 这里的self.subviews.count不要单独赋值给其他变量 while (self.subviews.count < photosCount) { HWStatusPhotoView *photoView = [[HWStatusPhotoView alloc] init]; [self addSubview:photoView]; } // 遍历所有的图片控件,设置图片 for (int i = 0; i<self.subviews.count; i++) { HWStatusPhotoView *photoView = self.subviews[i]; if (i < photosCount) { // 显示 photoView.photo = photos[i]; photoView.hidden = NO; } else { // 隐藏 photoView.hidden = YES; } } } - (void)layoutSubviews { [super layoutSubviews]; // 设置图片的尺寸和位置 int photosCount = self.photos.count; int maxCol = HWStatusPhotoMaxCol(photosCount); for (int i = 0; i<photosCount; i++) { HWStatusPhotoView *photoView = self.subviews[i]; int col = i % maxCol; photoView.x = col * (HWStatusPhotoWH + HWStatusPhotoMargin); int row = i / maxCol; photoView.y = row * (HWStatusPhotoWH + HWStatusPhotoMargin); photoView.width = HWStatusPhotoWH; photoView.height = HWStatusPhotoWH; } } + (CGSize)sizeWithCount:(int)count { // 最大列数(一行最多有多少列) int maxCols = HWStatusPhotoMaxCol(count); int cols = (count >= maxCols)? maxCols : count; CGFloat photosW = cols * HWStatusPhotoWH + (cols - 1) * HWStatusPhotoMargin; // 行数 int rows = (count + maxCols - 1) / maxCols; CGFloat photosH = rows * HWStatusPhotoWH + (rows - 1) * HWStatusPhotoMargin; return CGSizeMake(photosW, photosH); } @end ~~~ photo的代码 ~~~ #import "HWStatusPhotoView.h" #import "HWPhoto.h" #import "UIImageView+WebCache.h" @interface HWStatusPhotoView() @property (nonatomic, weak) UIImageView *gifView; @end @implementation HWStatusPhotoView - (UIImageView *)gifView { if (!_gifView) { UIImage *image = [UIImage imageNamed:@"timeline_image_gif"]; UIImageView *gifView = [[UIImageView alloc] initWithImage:image]; [self addSubview:gifView]; self.gifView = gifView; } return _gifView; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // 内容模式 self.contentMode = UIViewContentModeScaleAspectFill; // 超出边框的内容都剪掉 self.clipsToBounds = YES; } return self; } - (void)setPhoto:(HWPhoto *)photo { _photo = photo; // 设置图片 [self sd_setImageWithURL:[NSURL URLWithString:photo.thumbnail_pic] placeholderImage:[UIImage imageNamed:@"timeline_image_placeholder"]]; // 显示\隐藏gif控件 // 判断是够以gif或者GIF结尾 self.gifView.hidden = ![photo.thumbnail_pic.lowercaseString hasSuffix:@"gif"]; } - (void)layoutSubviews { [super layoutSubviews]; self.gifView.x = self.width - self.gifView.width; self.gifView.y = self.height - self.gifView.height; } @end ~~~ ## 三:注意地方 ### 显示\隐藏gif控件 ~~~ // 判断是够以gif或者GIF结尾 self.gifView.hidden = ![photo.thumbnail_pic.lowercaseString hasSuffix:@"gif"]; ~~~ ### 字符串分类根据字符串字体和最大宽度来得到所占据的高度宽度 ~~~ /** * 根据字符串字体和最大宽度来得到所占据的高度宽度 * * @param font 字体 * @param maxW 最大宽度 * * @return 长宽size */ - (CGSize)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW { NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; attrs[NSFontAttributeName] = font; CGSize maxSize = CGSizeMake(maxW, MAXFLOAT); return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; } /** * 在宽度为最大值时候根据字体得到宽高 * * @param font 字体 * * @return 长宽size */ - (CGSize)sizeWithFont:(UIFont *)font { return [self sizeWithFont:font maxW:MAXFLOAT]; } ~~~ ### UIImageView图片设置 ~~~ /** UIViewContentModeScaleToFill : 图片拉伸至填充整个UIImageView(图片可能会变形) UIViewContentModeScaleAspectFit : 图片拉伸至完全显示在UIImageView里面为止(图片不会变形) UIViewContentModeScaleAspectFill : 图片拉伸至 图片的宽度等于UIImageView的宽度 或者 图片的高度等于UIImageView的高度 为止 UIViewContentModeRedraw : 调用了setNeedsDisplay方法时,就会将图片重新渲染 UIViewContentModeCenter : 居中显示 UIViewContentModeTop, UIViewContentModeBottom, UIViewContentModeLeft, UIViewContentModeRight, UIViewContentModeTopLeft, UIViewContentModeTopRight, UIViewContentModeBottomLeft, UIViewContentModeBottomRight, 经验规律: 1.凡是带有Scale单词的,图片都会拉伸 2.凡是带有Aspect单词的,图片都会保持原来的宽高比,图片不会变形 */ // 内容模式self(imageView对象) self.contentMode = UIViewContentModeScaleAspectFill; // 超出边框的内容都剪掉 self.clipsToBounds = YES; ~~~