本来第二季是快写好了, 也花了点功夫, 结果gitbook出了点问题, 给没掉了。有些细节可能会一带而过, 如有疑问, 相互交流进步~.
菜单栏还没做出, 不能发消息。
第四步:
我们打开StoryBoard。拖入和左边一样的两个控件ImageView和UIButton。并设置和左边一样的约束。具体的约束思路如下:
1.设置ImageView距离右边10 , 宽高为40==》确定了x,和宽高
2.设置ImageView的上面和timeLabel下面对齐 ==》确定了Y, 确定了Button
3.设置Button右边距离ImageView左边10, 固定宽高。
4.设置Button的上面与ImageView上面对齐。
SB图片如下:
修改完SB的cell界面后开始编码了。我们主要需要在setMessage这个setter方法中, 加入判断聊天消息是属于左边还是属于右边。具体逻辑如下:
- (void)setMessage:(Message *)message { _message = message; MessageWhoIsMe == _message.type? [self setShowButton: _rightText andIcon: _rightIcon withMessage:message]: [self setShowButton: _text andIcon: _icon withMessage:message];}/** * 设置要展示的消息内容与头像 * * @param button 设置要显示的信息。 * @param icon 设置要显示的头像 */- (void)setShowButton:(UIButton *)text andIcon:(UIImageView *)icon withMessage:(Message*)message{ _rightIcon.hidden = _rightText.hidden = (text != _rightText); _icon.hidden = _text.hidden = (text != _text); // 1.给控件装数据 icon.image = [UIImage imageNamed:[self getPicture: message.type]]; [text setTitle:message.text forState:UIControlStateNormal]; _timeLabel.text = message.time; // 2.装完数据强制布局, 使得设置按钮高度的值准确, 并且更新约束 [text layoutIfNeeded]; // 要先强制布局, 这时候更新约束才准确 // 更新约束, 使得按钮的高度此时等于文本的高度。 [text updateConstraints:^(MASConstraintMaker *make) { CGFloat textH = CGRectGetHeight(text.titleLabel.frame); //+ 30; make.height.equalTo(textH); }]; // 3.再次强制布局, 使得约束生效, 这样获取到的按钮高度才准确 [text layoutIfNeeded]; CGFloat textH = CGRectGetMaxY(text.frame); CGFloat iconH = CGRectGetMaxY(icon.frame); CGFloat cellH = MAX(textH, iconH) + 10; // 4.更新cell的高度到模型中 message.height = cellH;}
效果图如下(已经实现了左右排列):
[UIImage resizeWithImageName:
的知识点。 .....省略N行代码 _timeLabel.text = message.time; // 1.2 改进背景图。 if (!_rightText.hidden) { // 当前显示的是右边, 则设置右边的背景 [_rightText setBackgroundImage:[UIImage resizeWithImageName:@"chat_send_nor"] forState:UIControlStateNormal]; [_rightText setBackgroundImage:[UIImage resizeWithImageName:@"chat_send_PRess_pic"] forState:UIControlStateHighlighted]; }else { // 显示的是左边 [_text setBackgroundImage:[UIImage resizeWithImageName:@"chat_recive_press_pic"] forState:UIControlStateNormal]; [_text setBackgroundImage:[UIImage resizeWithImageName:@"chat_recive_nor"] forState:UIControlStateHighlighted]; } // 2.装完数据强制布局, 使得设置按钮高度的值准确, 并且更新约束 .....省略N行代码
UIImage resizeWithImageName:
替换成UIImage imageNamed:
来加载图片, 会发现,当按钮中的文字变大时候,图片还是那么大,也就说图片没有随着按钮的尺寸进行伸缩。好在苹果已经为我们提供了一个方法来伸缩图片。其实UIImage resizeWithImageName:
只是我对Apple官方的方法的一个封装, 并将它做成UIImage的分类细说-(UIImage *)resizableImageWithCapInsets:
这个方法是Apple提供的Image类的实例方法。为了不误导大家, 特意查了官方解释如下:
1.简单来说该方法是用来返回一个可随着Button尺寸自动伸缩的图片,并且能保留住原来图片的四个边角, 也就说你要把它设置成Button的背景图。
2.该方法主要通过保护区域是不是有宽、高,和保护区域的大小来决定渲染的方式。当保护区域有高该图片就是竖直可伸缩, 有宽则是水平可伸缩。当宽高都是1px时候,选用的渲染方式是直接把这1px的图片扯大, 渲染的效率十分高。
那么究竟如何确定保护区域呢?根据官方文档,我们最好将保护区域设置成1*1的大小。这样水平、竖直方向都可以进行拉伸, 并且渲染方式也高, 还有一点就是这个区域我们最好选择的是最靠近正中间的, 因为一般来说这样才能尽可能把图片边缘切掉, 保证渲染出来的图片和远图片看上去是放大后的效果。否则可能出现,图片存在菱角。当然我们还能通过resizableImageWithCapInsets:resizingMode:
来说明图片渲染的模式,一种是使用拉伸来resize图片, 一种是使用平铺的方式来resize图片.说了那么多, 你应该懂得了原理, 那么直接看我给UIImage扩充的分类方法吧。
#import "UIImage+Resizingable.h"@implementation UIImage (Resizingable)+ (UIImage *)resizeWithImageName:(NSString *)imageName { UIImage * image = [UIImage imageNamed: imageName]; int W = image.size.width * 0.5; int H = image.size.height * 0.5; return [image resizableImageWithCapInsets: UIEdgeInsetsMake(H, W, image.size.height - H - 1 , image.size.width - W - 1)];}@end
第五步-1效果图:
- (void)awakeFromNib
方法中- (void)awakeFromNib { // 设置自动换行 _text.titleLabel.numberOfLines = 0; _rightText.titleLabel.numberOfLines = 0; // 设置button的内边距 _text.contentEdgeInsets = UIEdgeInsetsMake(0, 30, 0, 30); _rightText.contentEdgeInsets = UIEdgeInsetsMake(0, 30, 0, 30);}
更改Button的高度约束,多加30
[text updateConstraints:^(MASConstraintMaker *make) { CGFloat textH = CGRectGetHeight(text.titleLabel.frame)+ 30; make.height.equalTo(textH); }];
我觉得你会对内边距存在很大的疑惑, 请看我的博客有专门介绍了下内边距。
最终效果图如下:
时间有限,菜单栏还介绍, 敬请关注第三季。
新闻热点
疑难解答