zoukankan      html  css  js  c++  java
  • UI基础之UITableView案例QQ聊天界面

    数据模型:

    #import <Foundation/Foundation.h>
    
    typedef enum{
        LLMessageTypeMe,
        LLMessageTypeOther
    }LLMessageType;
    
    @interface LLMessage : NSObject
    
    /**
     *  time
     */
    @property (nonatomic, copy) NSString *time;
    
    /**
     *  text
     */
    @property (nonatomic, copy) NSString *text;
    
    /**
     *  type 定义为枚举类型的好处
     */
    @property (nonatomic, assign) LLMessageType type;
    
    /**
     *  hiddenTime 时间是否隐藏
     */
    @property (nonatomic, assign, getter=isHiddenTime) BOOL hiddenTime;
    
    - (instancetype)initWithDic:(NSDictionary *)dic;
    + (instancetype)messageWithDic:(NSDictionary *)dic;
    
    + (NSMutableArray *)messageList;
    
    @end
    #import "LLMessage.h"
    
    @implementation LLMessage
    
    - (instancetype)initWithDic:(NSDictionary *)dic
    {
        if (self = [super init]) {
            [self setValuesForKeysWithDictionary:dic];
        }
        return self;
    }
    
    + (instancetype)messageWithDic:(NSDictionary *)dic
    {
        return [[self alloc] initWithDic:dic];
    }
    
    + (NSMutableArray *)messageList
    {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"messages" ofType:@"plist"];
        NSArray *dicArr = [NSArray arrayWithContentsOfFile:path];
        
        NSMutableArray *tmpArr = [[NSMutableArray alloc] initWithCapacity:dicArr.count];
        for (NSDictionary *dic in dicArr) {
            LLMessage *endMessage = [tmpArr lastObject];
            LLMessage *message = [LLMessage messageWithDic:dic];
            
            if ([message.time isEqualToString:endMessage.time]) {
                
                message.hiddenTime = YES;
            }
            
            [tmpArr addObject:message];
        }
        return tmpArr;
    }
    
    @end

    frame模型

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    #define LLTIMEFONT [UIFont systemFontOfSize:12]
    #define LLTEXTFONT [UIFont systemFontOfSize:13]
    #define LLPADDING 20
    @class LLMessage;
    @interface LLMessageFrame : NSObject
    
    @property (nonatomic, strong) LLMessage *message;
    
    @property (nonatomic, assign,readonly) CGRect timeF;
    
    @property (nonatomic, assign, readonly) CGRect textF;
    
    @property (nonatomic, assign, readonly) CGRect iconF;
    
    @property (nonatomic, assign, readonly) CGFloat cellHeight;
    
    + (NSMutableArray *)messageFrameList;
    
    @end
    #import "LLMessageFrame.h"
    #import "LLMessage.h"
    #import "NSString+LLNSStringExtension.h"
    @implementation LLMessageFrame
    
    + (NSMutableArray *)messageFrameList
    {
        NSMutableArray *messageArr = [LLMessage messageList];
        NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithCapacity:messageArr.count];
        for (LLMessage *message in messageArr) {
            LLMessageFrame *frame = [[LLMessageFrame alloc] init];
            frame.message = message;
            [tmpArray addObject:frame];
        }
        return tmpArray;
    }
    
    - (void)setMessage:(LLMessage *)message
    {
        _message = message;
        
        CGFloat margin = 10;
        // 时间
        CGFloat timeX = 0;
        CGFloat timeY = 0;
        CGFloat timeW = 320;
        CGFloat timeH = 40;
        if (!message.isHiddenTime){
            _timeF = CGRectMake(timeX, timeY, timeW, timeH);
        }
        
        // icon
        CGFloat iconY = CGRectGetMaxY(_timeF);
        CGFloat iconWH = 30;
        CGFloat iconX;
        if (message.type == LLMessageTypeMe) { // Me
            
            iconX = timeW - iconWH - margin;
        } else { // Other
            
            iconX = margin;
        }
        _iconF = CGRectMake(iconX, iconY, iconWH, iconWH);
        
        // text
        CGFloat textY = iconY;
        CGSize textSize = [message.text textOfSize:CGSizeMake(200, MAXFLOAT) font:LLTEXTFONT];
        CGSize buttonSize = CGSizeMake(textSize.width + LLPADDING * 2, textSize.height + LLPADDING * 2);
        CGFloat textX;
        if (message.type == LLMessageTypeMe) { // Me
            
            textX = iconX - margin - buttonSize.width;
        } else {
            
            textX = CGRectGetMaxX(_iconF) + margin;
        }
        _textF = (CGRect){{textX, textY} , buttonSize};
        
        CGFloat textMaxY = CGRectGetMaxY(_textF);
        CGFloat iconMaxY = CGRectGetMaxY(_iconF);
        
        _cellHeight = MAX(textMaxY, iconMaxY);
        
    }
    
    @end

    代码自定义cell

    #import <UIKit/UIKit.h>
    @class LLMessageFrame;
    @interface LLMessageCell : UITableViewCell
    
    @property (nonatomic, strong) LLMessageFrame *messageFrame;
    
    + (instancetype)messageCellWith:(UITableView *)tableView;
    
    @end
    #import "LLMessageCell.h"
    #import "LLMessageFrame.h"
    #import "LLMessage.h"
    #import <UIKit/UIKit.h>
    #import "UIImage+LLUIImageExtension.h"
    @interface LLMessageCell ()
    
    @property (nonatomic, weak) UILabel *timeView;
    @property (nonatomic, weak) UIImageView *iconView;
    @property (nonatomic, weak) UIButton *textView;
    
    @end
    
    @implementation LLMessageCell
    
    + (instancetype)messageCellWith:(UITableView *)tableView
    {
        static NSString *ID = @"messageCell";
        LLMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
        if (!cell) {
            
            cell = [[LLMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        }
        return cell;
    }
    
    - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
            
            // 创建cell子控件
            self.backgroundColor = [UIColor clearColor];
            // time
            UILabel *timeView = [[UILabel alloc] init];
            [self.contentView addSubview:timeView];
            timeView.textAlignment = NSTextAlignmentCenter;
            timeView.font = LLTIMEFONT;
            self.timeView = timeView;
            
            // icon
            UIImageView *iconView = [[UIImageView alloc] init];
            [self.contentView addSubview:iconView];
            self.iconView = iconView;
            
            // text
            UIButton *textView = [[UIButton alloc] init];
            [self.contentView addSubview: textView];
            textView.titleLabel.font = LLTEXTFONT;
            textView.titleLabel.numberOfLines = 0;
            textView.contentEdgeInsets = UIEdgeInsetsMake(LLPADDING, LLPADDING, LLPADDING, LLPADDING);
            self.textView = textView;
            
            
        }
        return self;
    }
    
    - (void)setMessageFrame:(LLMessageFrame *)messageFrame
    {
        _messageFrame = messageFrame;
        
        // 1,设置数据
        [self setDate];
        
        // 2,设置frame
        [self setSubviewsFrame];
    }
    
    - (void)setDate
    {
        LLMessage *message = self.messageFrame.message;
        self.timeView.text = message.time;
        
        NSString *iconName = message.type == LLMessageTypeMe ? @"me" : @"other";
        self.iconView.image = [UIImage imageNamed:iconName];
        // 设置图片背景
        
        
    #warning 设置按钮上label字体方法
        [self.textView setTitle:message.text forState:UIControlStateNormal];
        if (message.type == LLMessageTypeMe) {
            [self.textView setBackgroundImage:[UIImage registerImage:@"chat_send_nor"] forState:UIControlStateNormal];
            [self.textView setBackgroundImage:[UIImage registerImage:@"chat_send_press_pic"] forState:UIControlStateHighlighted];
            [self.textView setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        } else {
            [self.textView setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
            [self.textView setBackgroundImage:[UIImage registerImage:@"chat_recive_nor"] forState:UIControlStateNormal];
            [self.textView setBackgroundImage:[UIImage registerImage:@"chat_recive_press_pic"] forState:UIControlStateHighlighted];
        }
    }
    
    - (void)setSubviewsFrame
    {
        self.timeView.frame = self.messageFrame.timeF;
        self.iconView.frame = self.messageFrame.iconF;
        self.textView.frame = self.messageFrame.textF;
    }
    
    
    @end

    分类:NSString

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface NSString (LLNSStringExtension)
    
    - (CGSize)textOfSize:(CGSize)maxSize font:(UIFont *)font;
    
    @end
    
    #import "NSString+LLNSStringExtension.h"
    
    @implementation NSString (LLNSStringExtension)
    
    - (CGSize)textOfSize:(CGSize)maxSize font:(UIFont *)font
    {
        return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil].size;
    }
    
    @end

    UIImage分类

    #import <UIKit/UIKit.h>
    
    @interface UIImage (LLUIImageExtension)
    
    + (UIImage *)registerImage:(NSString *)imageName;
    
    @end
    
    
    
    #import "UIImage+LLUIImageExtension.h"
    #import <UIKit/UIKit.h>
    @implementation UIImage (LLUIImageExtension)
    
    + (UIImage *)registerImage:(NSString *)imageName
    {
        UIImage * image = [UIImage imageNamed:imageName];
        return [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5];
    }
    
    @end

    controller:

    #import "ViewController.h"
    #import "LLMessageFrame.h"
    #import "LLMessage.h"
    #import "LLMessageCell.h"
    
    @interface ViewController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate>
    
    @property (nonatomic, strong) NSMutableArray *messageFrames;
    
    @property (weak, nonatomic) IBOutlet UITableView *tableView;
    
    @property (weak, nonatomic) IBOutlet UIView *footerView;
    @property (weak, nonatomic) IBOutlet UITextField *textField;
    
    @end
    
    @implementation ViewController
    
    #pragma mark - 懒加载数据模型
    - (NSMutableArray *)messageFrames
    {
        if (!_messageFrames) {
            
           _messageFrames = [LLMessageFrame messageFrameList];
        }
        return _messageFrames;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        // 隐藏分割线
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        
        // 取消tableView的点击
        self.tableView.allowsSelection = NO;
    
        self.tableView.backgroundColor = [UIColor colorWithRed:240/255.0 green:224/255.0 blue:224/255.0 alpha:1.0];
        
        // 监听通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clickTextFiled:) name:UIKeyboardWillChangeFrameNotification object:nil];
        
        // 设置文本框左边内容默认有间距
        self.textField.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 0)];
        self.textField.leftViewMode = UITextFieldViewModeAlways;
    }
    
    - (void)clickTextFiled:(NSNotification *)noti
    {
        CGRect rect = [noti.userInfo[@"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
        CGFloat moveY = rect.origin.y - self.view.frame.size.height;
        self.view.transform = CGAffineTransformMakeTranslation(0, moveY);
    }
    
    - (void)dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    #pragma mark - 数据源方法
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.messageFrames.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // 1,创建cell
        LLMessageCell *cell = [LLMessageCell messageCellWith:tableView];
        
        // 2,设置cell
        cell.messageFrame = self.messageFrames[indexPath.row];
        
        return cell;
    }
    
    #pragma mark - 代理方法
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return [self.messageFrames[indexPath.row] cellHeight];
    }
    
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        [self.view endEditing:YES];
    }
    
    #pragma mark - 文本框代理方法
    - (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        LLMessageFrame *frame = [[LLMessageFrame alloc] init];
        LLMessage *message = [[LLMessage alloc] init];
        NSDate *date = [NSDate date];
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"hh:mm";
        NSString *time = [formatter stringFromDate:date];
        message.time = time;
        message.text = textField.text;
        message.type = LLMessageTypeMe;
        LLMessageFrame *lastMF = [self.messageFrames lastObject];
        if ([lastMF.message.time isEqualToString:message.time]) {
            message.hiddenTime = YES;
        }
            frame.message = message;
        [self.messageFrames addObject:frame];
        
        // 刷新
        [self.tableView reloadData];
        
        // 自动上滚
        NSIndexPath *path = [NSIndexPath indexPathForRow:self.messageFrames.count - 1 inSection:0];
        [self.tableView scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        
        
        textField.text = nil;
        return YES;
    }
    
    - (BOOL)prefersStatusBarHidden
    {
        return YES;
    }
    
    @end

    效果;

  • 相关阅读:
    CSS浏览器兼容----IE的定制CSS样式
    CSS浏览器兼容---判断IE版本的HTM语句
    单链表操作1
    数学建模1
    浏览器内核学习笔记二
    浏览器内核学习笔记一
    网页使用特殊字体
    SQL Server 2008 R2没有卸载干净
    RadioButtonFor绑定值
    SVN 服务启动报错 0x8007042a
  • 原文地址:https://www.cnblogs.com/-boy/p/4133663.html
Copyright © 2011-2022 走看看