国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

QQ聊天界面的布局和設計(IOS篇)-第二季

2019-11-14 18:52:56
字體:
來源:轉載
供稿:網友

QQChat Layout - 第二季

  • 本來第二季是快寫好了, 也花了點功夫, 結果gitbook出了點問題, 給沒掉了。有些細節可能會一帶而過, 如有疑問, 相互交流進步~.

    在第一季中我們完成了QQ聊天界面的基本框架.但是相對于iphone上手機QQ的聊天界面還存在以下差距。

  • 第二季中的工程源文件下載地址:點擊到百度云下載
  • 聊天消息沒有左右區分。
  • 聊天內容沒有背景圖片。
  • 菜單欄還沒做出, 不能發消息。

現在我們就一步步來解決這些問題。首先我們解決消息沒有左右區分的問題。

  • 第四步:
    我們打開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;}

效果圖如下(已經實現了左右排列):

  • 第五步:
  • 我們已經完成了QQ消息的可以分左右排列, 接下去我們需要給消息上背景圖, 也就是設置按鈕的背景圖。由于按鈕有狀態,所以你不能操作它的圖片控件來給它設置圖, 應該用其提供的設置圖片的接口。具體的邏輯比較簡單。你可以直接看代碼,我主要講下[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效果圖:

  • 你一定會看出還存在一點問題。問什么文字沒有全部被背景包括著,這是因為很多時候美工給的圖片背景都會有留白問題。也就是不是沒有被圖片包括著,是因為圖片旁邊有一些空白,顯示出來就成這樣了。這是后我們又可以利用按鈕的內邊距來把Label向左右推,這樣Label就會變高了,會超出Button,所以我們需要再給Button加點高度。應為給Button設置內邊距只需要設置一次,所以我一般將這種操作方法- (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);    }];

我覺得你會對內邊距存在很大的疑惑, 請看我的博客有專門介紹了下內邊距。

最終效果圖如下:

時間有限,菜單欄還介紹, 敬請關注第三季。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿克苏市| 收藏| 仁化县| 宣化县| 开平市| 开平市| 察雅县| 衡水市| 萨迦县| 阳高县| 皋兰县| 屏南县| 巴彦县| 石楼县| 绩溪县| 麟游县| 华宁县| 梁河县| 澄城县| 大理市| 大足县| 天峨县| 淮北市| 洪雅县| 哈尔滨市| 金昌市| 清河县| 荃湾区| 夏邑县| 岗巴县| 涟源市| 孝昌县| 汉源县| 志丹县| 沙田区| 平昌县| 饶平县| 竹山县| 芜湖县| 高雄市| 花垣县|