AJ学IOS 之微博项目实战(10)微博cell中图片的显示以及各种填充模式简介
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中图片的显示以及各种填充模式简介的更多相关文章
- AJ学IOS 之微博项目实战(1)微博主框架-子控制器的添加
AJ分享,必须精品 一:简单介绍 这是新浪微博的iOS端项目,来自于黑马的一个实战项目. 主要分成五大模块,本次全部运用纯代码实现,其中会用到很多前面学过得内容,如果有的地方有重复的知识点,说明这个知 ...
- AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController
AJ分享,必须精品 一:添加导航控制器 上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController). 为啥要做自定义呢,因为为了更好地封 ...
- 猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController
猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一:加入导航控制器 上一篇博 ...
- AJ学IOS 之微博项目实战(5)微博自定义搜索框searchBar
AJ分享,必须精品 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [ ...
- AJ学IOS 之微博项目实战(9)微博模型之时间相关重要操作,判断刚刚,昨天,今年等等
AJ分享,必须精品 一:效果 二:实现代码 /** 1.今年 1> 今天 * 1分内: 刚刚 * 1分~59分内:xx分钟前 * 大于60分钟:xx小时前 2> 昨天 * 昨天 xx:xx ...
- AJ学IOS 之微博项目实战(4)微博自定义tabBar中间的添加按钮
AJ分享,必须精品 一:效果图 自定义tabBar实现最下面中间的添加按钮 二:思路 首先在自己的tabBarController中把系统的tabBar设置成自己的tabBar(NYTabBar),这 ...
- AJ学IOS 之微博项目实战(3)微博主框架-UIImage防止iOS7之后自动渲染_定义分类
AJ分享,必须精品 一:效果对比 当我们设置tabBarController的tabBarItem.image的时候,默认情况下会出现图片变成蓝色的效果,这是因为ios7之后会对图片自动渲染成蓝色 代 ...
- 猫猫学iOS 之微博项目实战(5)微博自己定义搜索框searchBar
猫猫分享.必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用 ...
- AJ学IOS 之微博项目实战(8)用AFNetworking和SDWebImage简单加载微博数据
AJ分享,必须精品 一:效果 没有图文混排,也没有复杂的UI,仅仅是简单的显示出微博数据,主要介绍AFNetworking和SDWebImage的简单用法 二:加载数据AFNetworking AFN ...
随机推荐
- Blazor-断开连接后重新加载浏览器
在大多数情况下,Blazor将与以前相同的线路上重新连接到服务器.但有时无法重新连接,需要重新加载web浏览器才能使网站重新工作.如果服务器回收应用程序池,则需要手动重新加载页面在没有调试的情况下在I ...
- IntegerCache缓存占用堆、栈、常量池的问题,自动拆装箱的基本概念,Integer==int时的问题说明
原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 先普及一个基本概念:Java中基本数据类型的装箱和拆箱操作 自动装箱 在JDK5以后,我们 ...
- 常用正则表达式(手机号、邮箱、URL地址、身份证等等)
一.前言 不好的习惯:1.每一次用到正则都是上网copy一份,也没有去学习思考,看看都是什么意思: 2.一个项目里不同的地方用到了相同的校验,一直在重复的copy代码,并没有统一起来,万一哪天要修改规 ...
- Windows下利用Chrome调试IOS设备页面
本文介绍如何在 Windows 系统中连接 iOS设备 并对 Web 页面进行真机调试 必须前提 iOS设备.数据线 Node.js 环境 Chrome 浏览器 环境准备 安装Node环境 参考Nod ...
- 微信开发+百度AI学习:环境搭建
注册成为百度开发者,百度接入指南http://ai.baidu.com/docs#/Begin/top 选择分类进去创建应用,接口权限全部选择好了,这样就可以只创建一个应用就有全部接口权限. C#开发 ...
- hdu1213 并查集板子
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1213/ 并查集是一种支持合并与查找的数据结构,在森林中进行操作,加上路径压缩,合并和查找的时间复杂度几乎都是常数 ...
- 第十八周java实验作业
实验十八 总复习 实验时间 2018-12-30 1.实验目的与要求 (1) 综合掌握java基本程序结构: (2) 综合掌握java面向对象程序设计特点: (3) 综合掌握java GUI 程序设 ...
- JavaWeb----Cookie&Session
## 会话技术 1.会话:一次会话中包含多次请求和响应. * 第一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止. 2.功能:再一次会话的范围内的多次请求间,共享数据 3. ...
- golang工具之present - 编写go特色的ppt
简介: Golang Present 是 Golang 社群开发出來的一个简单工具,通过简单的语法可以制作 ppt(语法近似于 Markdown). 默认文件格式是 .slide ,是随着 gol ...
- Worktile正式入驻飞书,助力企业轻松实现敏捷开发与协作
企业在敏捷研发中时常面临着交付延期.需求不匹配等问题,如何更高效地完成敏捷研发? Worktile携手飞书,为企业用户提供敏捷开发服务,帮助企业实现软件项目的需求管理.缺陷追踪.迭代规划与推进以及效能 ...