AJ分享,必须精品

:一效果

如果直接设置会有拉伸等等的状况,这里主要介绍图片显示的一些细节

二:代码

代码实现其实很简单,微博当中用了一个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;

AJ学IOS 之微博项目实战(10)微博cell中图片的显示以及各种填充模式简介的更多相关文章

  1. AJ学IOS 之微博项目实战(1)微博主框架-子控制器的添加

    AJ分享,必须精品 一:简单介绍 这是新浪微博的iOS端项目,来自于黑马的一个实战项目. 主要分成五大模块,本次全部运用纯代码实现,其中会用到很多前面学过得内容,如果有的地方有重复的知识点,说明这个知 ...

  2. AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController

    AJ分享,必须精品 一:添加导航控制器 上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController). 为啥要做自定义呢,因为为了更好地封 ...

  3. 猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController

    猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一:加入导航控制器 上一篇博 ...

  4. AJ学IOS 之微博项目实战(5)微博自定义搜索框searchBar

    AJ分享,必须精品 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [ ...

  5. AJ学IOS 之微博项目实战(9)微博模型之时间相关重要操作,判断刚刚,昨天,今年等等

    AJ分享,必须精品 一:效果 二:实现代码 /** 1.今年 1> 今天 * 1分内: 刚刚 * 1分~59分内:xx分钟前 * 大于60分钟:xx小时前 2> 昨天 * 昨天 xx:xx ...

  6. AJ学IOS 之微博项目实战(4)微博自定义tabBar中间的添加按钮

    AJ分享,必须精品 一:效果图 自定义tabBar实现最下面中间的添加按钮 二:思路 首先在自己的tabBarController中把系统的tabBar设置成自己的tabBar(NYTabBar),这 ...

  7. AJ学IOS 之微博项目实战(3)微博主框架-UIImage防止iOS7之后自动渲染_定义分类

    AJ分享,必须精品 一:效果对比 当我们设置tabBarController的tabBarItem.image的时候,默认情况下会出现图片变成蓝色的效果,这是因为ios7之后会对图片自动渲染成蓝色 代 ...

  8. 猫猫学iOS 之微博项目实战(5)微博自己定义搜索框searchBar

    猫猫分享.必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用 ...

  9. AJ学IOS 之微博项目实战(8)用AFNetworking和SDWebImage简单加载微博数据

    AJ分享,必须精品 一:效果 没有图文混排,也没有复杂的UI,仅仅是简单的显示出微博数据,主要介绍AFNetworking和SDWebImage的简单用法 二:加载数据AFNetworking AFN ...

随机推荐

  1. React Native实现短信转发到微信上

    缘由 都说需求来源于生活我为什么会有一个这么奇葩的需求呢?来看一个故事. 昨天为了省点手续费导航走了3公里多去找一家工行ATM机(没办法穷)然后到了以后发现ATM机在人家的园区里面,现在疫情进入要通行 ...

  2. Unity 游戏框架:命名的力量--变量

    变量的命名入门 大家先来试着理解一下这段代码: var todoList = new TodoList(); todoList.Todos = new List<Todo>(); var ...

  3. nmap端口扫描工具安装和使用方法

    nmap(Network Mapper)是一款开源免费的针对大型网络的端口扫描工具,nmap可以检测目标主机是否在线.主机端口开放情况.检测主机运行的服务类型及版本信息.检测操作系统与设备类型等信息. ...

  4. [二分,multiset] 2019 Multi-University Training Contest 10 Welcome Party

    Welcome Party Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)T ...

  5. UVA - 548 根据中序遍历和后序遍历建二叉树(关于三种遍历二叉树)

    题意: 同时给两个序列,分别是二叉树的中序遍历和后序遍历,求出根节点到叶子结点路径上的权值最小和 的那个 叶子节点的值,若有多个最小权值,则输出最小叶子结点的和. 想法: 一开始想着建树,但是没有这样 ...

  6. coding++:java-自定义签名+拦截器

    本次案例工具为:SpringBoot   <version>1.5.19.RELEASE</version> Code: 1.annotations package com.m ...

  7. Javascript/Jquery实现日期前一天后一天

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  8. python学习第四节 迭代器 生成器

    1:什么是迭代 可以直接作用于for循环的对象统称为可迭代对象(Iterable). 可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator). 所有的Iterable均可以通 ...

  9. JAVA WEB随笔

    servlet生命周期: 1.构造器(单利)2.init(单例)3.service(多例,每次请求都会执行)4.销毁方法destroyservlet解析客户端请求流程:1.web客户端向servlet ...

  10. A AK的距离

    时间限制 : - MS   空间限制 : - KB  评测说明 : 1s,128m 问题描述 同学们总想AK.于是何老板给出一个由大写字母构成的字符串,他想你帮忙找出其中距离最远的一对'A'和'K'. ...