zoukankan      html  css  js  c++  java
  • oc学习之路----QQ聊天界面

    用到的技术:自定义cell,通知机制,代理模式 transform

      1.自定义cell(通过代码自定义cell)

        ①首先新建一个类继承UITableViewCell

        ②重写initWithStyle:reuseIdentifier方法

           这里只需要把所有要显示的子控件添加到contenView中,在这一步一般不需要设置属性的,       但是如果是一些子控件中一些静态的属性,字需要一次性设置的话,就在这里              设置,在重写frameSet方法的时候在把一些比较动态的数据填充上去以及设置

           每个子控件的frame

        ③提供两个模型

          数据模型:存放数据

          frame模型:通过拿到数据模型来计算每一个空间的frame,并设置为readOnly

      2.通知机制

        

    由此可见,我们可以这样认为 ,在一个程序运行过程中,有很多控件向通知中心发送通知,而我们可以随时随地的接收想要的通知,这点类似于代理,但是区别于的代理的是,通知比代理灵活,而且通知是多对多关系,一个对象可以告诉N个对象发生什么事情,一个对象能得知N个对象发生什么事情,而代理是一对一关系,一个对象只能告诉一个对象发生什么事情。

        通知发布

          

    - (void)postNotificationName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
    //发布一个名称为aName的通知,anObject为这个通知的发布者,aUserInfo为额外信息

        通知监听

    通知中心提供方法来注册一个监听通知的监听器(换言之就是,将自定义通知公之于世)

    - (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;
    /**
    observer:监听器,即谁要接收这个通知
    aSelector:收到通知后,回调监听器的这个方法,并且把通知对象当做参数传入
    aName:通知的名称。如果为nil,那么无论通知的名称是什么,监听器都能收到这个通知
    anObject:通知发布者。如果为anObject和aName都为nil,监听器都收到所有的通知*/

        取消注册监听器

          

    /*
    通知中心不会保留(retain)监听器对象,在通知中心注册过的对象,必须在该对象释放前取消注册。否则,当相应的通知再次出现时,通知中心仍然会向该监听器发送消息。因为相应的监听器对象已经被释放了,所以可能会导致应用崩溃
    
    通知中心提供了相应的方法来取消注册监听器
    */
    - (void)removeObserver:(id)observer;
    - (void)removeObserver:(id)observer name:(NSString *)aName object:(id)anObject;
    
    //一般在监听器销毁之前取消注册(如在监听器中加入下列代码):
    - (void)dealloc {
        //[super dealloc];  非ARC中需要调用此句
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }

        通知监听

          

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];

      3 代理模式

        简单步骤就是:一个协议 一个返回实现该协议的id类型的delegate 还有就是 在使用短实现协议,并且实现协议的方法

      

    难点:自定义cell,聊天图片的无变化拉伸,键盘的监听  

    思路:新建模型一个计算位置的,一个填充数据的

       新建View.用于显示每一个cell里面的数据m   

    细节:

      

    /**
    * 数据模型
    * MessageDataModel.m
    */
    @implementation MessageDataModel
    +(instancetype)messageWithDict:(NSDictionary *)dict{
        return [[self alloc] initWithDict:dict];
    }
    -(instancetype)initWithDict:(NSDictionary *)dict{
        if(self = [super init]){
            [self setValuesForKeysWithDictionary:dict];
        }
        return self;
    }
    @end
    /**
    * 位置模型
    * MessageFrameData.m
    */
    #define MJTextFont [UIFont systemFontOfSize:15]
    #import "MessageFrameData.h"
    #import "MessageDataModel.h"
    
    @implementation MessageFrameData
    -(void)setMessage:(MessageDataModel *)message {
        _message = message;
    //    间距
        CGFloat padding = 10;
    //    屏幕的宽度
        CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
        NSLog(@"==========%f",screenW);
    //    时间布局
        if(!message.hideTime){
            CGFloat timeX = 0;
            CGFloat timeY = 0;
            CGFloat timeW = screenW;
            CGFloat timeH = 40;
            _timeF = CGRectMake(timeX, timeY, timeW, timeH);
        }
    
    
    //    头像布局
        CGFloat iconY = CGRectGetMaxY(_timeF)+padding;
        CGFloat iconW = 40;
        CGFloat iconH = 40;
        CGFloat iconX;
        if(message.type == MessageTypeOther){//别人发的
            iconX = padding;
        } else{//自己发的
            iconX = screenW - padding -iconW;
        }
        _iconF = CGRectMake(iconX, iconY, iconW, iconH);
    
    //    正文
        CGFloat textY = iconY;
    //    能显示的最大size
        CGSize textMaxSize = CGSizeMake(150, MAXFLOAT);
    //    文本的真实size
        CGSize textSize = [self sizeWithText:message.text font:MJTextFont maxSize:textMaxSize];
    //    最终确定的size;
        CGSize textBtnSize = CGSizeMake(textSize.width+ TextPadding*2, textSize.height+ TextPadding*2);
        CGFloat textX;
        if(message.type == MessageTypeOther){
            textX = CGRectGetMaxX(_iconF)+padding;
        } else{
            textX = iconX - padding -textBtnSize.width;
        }
        _textF = (CGRect){{textX,textY},textBtnSize};
    //    _textF = CGRectMake(textX, textY, textSize.width, textSize.height);
    
        CGFloat textMaxY = CGRectGetMaxY(_textF);
        CGFloat iconMaxY = CGRectGetMaxY(_iconF);
        _cellHeight = MAX(textMaxY, iconMaxY) + padding;
    }
    /**
    *  计算文字尺寸
    *
    *  @param text    需要计算尺寸的文字
    *  @param font    文字的字体
    *  @param maxSize 文字的最大尺寸
    */
    - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize
    {
        NSDictionary *attrs = @{NSFontAttributeName : font};
        return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
    }
    @end
    /**
    * 自定义cell,用于填充数据和设置frame
    */
    #define MJTextFont [UIFont systemFontOfSize:15]
    #import "QQQViewCellTableViewCell.h"
    #import "MessageDataModel.h"
    #import "UIImage+Extension.h"
    
    @interface QQQViewCellTableViewCell()
    //内容
    @property (nonatomic, weak) UIButton *textView;
    //发送时间
    @property (nonatomic, weak) UIImageView *iconView;
    @property (nonatomic, weak)UILabel *timeView;
    @end
    
    @implementation QQQViewCellTableViewCell
    
    /**
    * 重写
    */
    -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    //        先调用父类方法
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self){
    //        子空间的创建和初始化
    //        时间
            UILabel *timeView = [[UILabel alloc] init];
            timeView.textAlignment = NSTextAlignmentCenter;
            timeView.textColor = [UIColor grayColor];
            timeView.font = [UIFont systemFontOfSize:13];
            [self.contentView addSubview:timeView];
            self.timeView = timeView;
    
    //       头像
            UIImageView *iconView = [[UIImageView alloc] init];
            [self.contentView addSubview:iconView];
            self.iconView = iconView;
    
    //        正文
            UIButton *textView = [[UIButton alloc] init];
            textView.titleLabel.numberOfLines = 0;
    //        textView.backgroundColor = [UIColor grayColor];
            textView.titleLabel.font = MJTextFont;
            [textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    //        设置内边距
            textView.contentEdgeInsets = UIEdgeInsetsMake(TextPadding, TextPadding, TextPadding, TextPadding);
            [self.contentView addSubview:textView];
            self.textView = textView;
    
    //        设置cell的背景颜色
            self.backgroundColor = [UIColor clearColor];
        }
        return self;
    }
    
    //这是布局
    -(void)setModel:(MessageFrameData *)model {
        _model = model;
        MessageDataModel *message = model.message;
    //    时间
        self.timeView.text = message.time;
        self.timeView.frame = model.timeF;
    //    头像
        NSString *icon = (message.type == MessageTypeOther)?@"other":@"me";
        self.iconView.image = [UIImage imageNamed:icon];
        self.iconView.frame = model.iconF;
    //    正文
        [self.textView setTitle:message.text forState:UIControlStateNormal];
        self.textView.frame = model.textF;
    //    设置正文背景图
        if (message.type == MessageTypeMe){
            [self.textView setBackgroundImage:[UIImage resizableImage:@"chat_send_nor"] forState:UIControlStateNormal];
        } else{
            [self.textView setBackgroundImage:[UIImage resizableImage:@"chat_recive_nor"] forState:UIControlStateNormal];
        }
    }
    
    
    +(instancetype)cellWithTableView:(UITableView *)tableView{
        static NSString *ID = @"qqmessage";
        QQQViewCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
        if(cell == nil){
            cell = [[QQQViewCellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        }
        return cell;
    }
    
    @end
  • 相关阅读:
    Distinct Substrings(spoj 694)
    Musical Theme
    Milk Patterns(poj 3261)
    Repeated Substrings(UVAlive 6869)
    喵星球上的点名(bzoj 2754)
    滑雪与时间胶囊(bzoj 2753)
    莫比乌斯函数之和(51nod 1244)
    欧拉函数之和(51nod 1239)
    数表(bzoj 3529)
    欧拉函数模板
  • 原文地址:https://www.cnblogs.com/superYou/p/4227498.html
Copyright © 2011-2022 走看看