本來第二季是快寫好了, 也花了點功夫, 結果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); }];
我覺得你會對內邊距存在很大的疑惑, 請看我的博客有專門介紹了下內邊距。
最終效果圖如下:
時間有限,菜單欄還介紹, 敬請關注第三季。
新聞熱點
疑難解答