即时通讯整个页面的搭建(二)

接着即时通讯整个页面的搭建(一)继续写

上一篇说完了控制器, 这一篇说说Cell, 底部ToolBar以及录音的显示的View, 约束嘛, 用的Masonry

IMBaseCell

这个属性是一个枚举值

typedef enum{
    IMBaseCellDefaultStyle = -1, // 默认状态  左边
    IMBaseCellLeftStyle, //左边的状态
    IMBaseCellRightStyle  // 右边的状态
} IMBaseCellStyle;

一开始是没有这个属性的, 直接就是一个isLeft判断, (当然正常的一个即时通讯的判断是不会放在外面的), 后来运行发现, Masony每一次reMake约束, 很耗时, 所以采用一个属性保存之前的样式, 和当前样式一样, 就不用再去改变约束了, 相对而言, 要提升一点流畅度

@property(nonatomic, assign)IMBaseCellStyle style;

这是一个Block属性, 是为了cell的Item变量改变,让控制器的数组的也同时更新,(一切显示靠模型去控制), 会有下载的进度的改变等等

@property(nonatomic, copy)void(^reloadCell)(IMBaseItem *messageItem);

查看图片, 以及播放视频的需要跳转, 很喜欢用block, 但是像这种情况还是选择了代理(具体哪里该使用代理, 哪里使用block, 不是很清楚, 有的人说block跟踪代码不方便, 代理点一下就跳过去了, 说的也是, 不过自己写的代码, 跟踪肯定是没问题的, 各有优劣吧, 全凭自己选择)

@property(nonatomic, weak)id<IMBaseCellDelegate> delegate;

看看让代理干了啥

/**
 *  点击视频,图片的代理方法
 *
 *  @param cell           点击的cell
 *  @param viewController 实例化好的控制器
 *  @param animated       是否动画过去
 *  @param completion     动画完成后要执行的代码
 */
- (void)IMBaseCell:(IMBaseCell *)cell presentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(void(^)())completion;
/**
 *  重新发送(发送失败的情况下)
 */
- (void)IMBaseCell:(IMBaseCell *)cell reSendMessage:(IMBaseItem *)message;
/**
 *  点击了语音播放(上一篇已经讲过连续播放)
 */
- (void)IMBaseCellClickAudioCell:(IMBaseCell *)cell;

cell里没有太多的逻辑代码, 其他的就是赋值了

其他就没有了(子弟动手,丰衣足食😀), 因为是demo, 并没有联网的, 所以上传,下载的进度, 运行时没有显示的, 代码已经注释了, 具体这个进度怎么监听的, 放到下一篇, 上传,下载的方法里(因为用的AFN2.x的版本, 并没有3.0里的block回调, 所以只能用kvo了),也是懵了一会,最后也想了这个办法解决, 有更好的方法,可以告诉我,不慎感激

下面说说底部的工具栏吧

IMChatToolBar

直接上代码

@property(nonatomic, weak)id<IMChatToolBarDelegate> delegate;

@property(nonatomic, weak)PlacehodeTextView *inputTextView;
/**
 *  实例化一个toolBar
 *
 *  @param frame          尺寸
 *  @param toolBarHeight  toolBar的高度
 *  @param moreViewHeight 更多的View的高度
 *
 *  @return 实例
 */
- (instancetype)initWithFrame:(CGRect)frame toolBarHeight:(CGFloat)toolBarHeight moreViewHeight:(CGFloat)moreViewHeight;
/**
 *  回到最底部
 */
- (void)backOriginalHeight;
/**
 *  隐藏
 */
- (void)hide;
/**
 *  显示
 */
- (void)show;

代理的方法

/**
 *  刷新消息
 */
- (void)IMChatToolBar:(IMChatToolBar *)chatToolBar imBaseItem:(IMBaseItem *)messageItem;
/**
 *  发送多条
 *
 *  @param schoolChatToolBar 
 *  @param messageItem       消息体
 */
- (void)IMChatToolBar:(IMChatToolBar *)chatToolBar sendIMBaseItem:(IMBaseItem *)messageItem;

/*
 *  键盘弹出  更新外部高度
 */
- (void)IMChatToolBar:(IMChatToolBar *)schoolChatToolBar ReloadHeight:(CGFloat)reloadHeight;

主要说一下更新高度, 这个给一个代理方法, 这个高度, 是toolBar的顶部具体屏幕底部的距离, 控制器的View拿到这个高度做响应的增减即可

具体看看实现吧 ↘️⤵️↙️
demo更多里值有拍照, 选择照片, 还有视频, 这里偷懒了, 因为选择照片这些都需要一个控制器的, 也是因为我自己知道, 我的toolBar代理是控制器才敢这么写的😋
应该加一层isKindIfClass判断

@property(nonatomic, weak)UIViewController *viewController;

- (void)setDelegate:(id<IMChatToolBarDelegate>)delegate{
    _delegate = delegate;
    self.viewController = (UIViewController *)delegate;
}

这么写的好处就是选择照片上传的代码就不用放在控制器里了, toolBar就能搞定,当然不一定合理(好用的就是合理的😀, 开玩笑啦), 所以基本上, 发送消息的活都让toolBar干了 控制器只要刷新数据就好了

说一个监听textView发送键的时间

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    
    if ([text isEqualToString:@"\n"]) {
        
        [self sendText:[self emotionText]];
        
        return NO;
    }
    
    return YES;
}

说到发送消息, 想到了自定义键盘时候(这里的键盘用的袁崢),表情编码与解码, 也是一个坑, 写好的正则表达式,在网站里测试是正常的到代码里就不行了, 只能采用暴力的方法解决(性能不好, 有好的方法可以讨论),例如匹配[1]这样的中括号中间是数字的字符串的正则表达式该怎么写(会的请评论一下喔,感激不尽)
既然要要自定义键盘, 那肯定要切换键盘了, 改变inputView即可
感兴趣的可以研究一下袁峥的表情键盘

self.emoticonButton.selected = !self.emoticonButton.isSelected;

if (self.emoticonButton.selected) {
        self.audioButton.hidden = YES;
        self.recordButton.selected = NO;
        self.inputTextView.yz_emotionKeyboard = self.emotionKeyboard;
        [self.inputTextView becomeFirstResponder];
    } else {
        self.inputTextView.yz_emotionKeyboard = nil;
        [self reloadInputViews];
}

上传下载发送消息的到下一篇再说吧

再看一下录音时候的提示,完全模仿微信的提示写的

IMVoiceVolumeView

/**
 *  根据声音大小显示不同view
 *
 *  @param volumn 声音的分贝大小
 */
- (void)volunmeWithSound:(CGFloat)volumn;
/**
 *  取消录音的样式
 */
- (void)volunmeViewCancel;
/**
 *  正常的样式
 */
- (void)volunmeViewNormal;
/**
 *  倒计时时间样式
 */
- (void)volunmeViewCountDown;
/**
 *  开始倒计时的方法
 */
- (void)volunmeViewCountDownBegin;
/**
 *  显示录音太短
 */
- (void)showShortTimeModel;
/**
 *  说话过长
 */
- (void)showLongTimeModel;

试了一下微信(平时经常用,但还真没留意过),大概就这个几种模式吧
看模式前,看一下按钮的监听方法

// 开始录音
- (void)recordButtonTouchDown
{
    self.volumeView.hidden = NO;
    [self.volumeView volunmeViewNormal];
}
// 取消录音
- (void)recordButtonTouchUpOutside// 滑出  并不在按钮上
{
    self.volumeView.hidden = YES;
}
// 完成录音
- (void)recordButtonTouchUpInside
{
    self.volumeView.hidden = YES;
    [[IMAudioTool shareAudioTool] startEncode];
}
// 滑出按钮  但按钮还在响应点击事件
- (void)recordDragOutside
{
    [self.volumeView volunmeViewCancel];
}
// 滑入按钮范围
- (void)recordDragInside
{
    [self.volumeView volunmeViewNormal];
}
  • 正常的样式

就是会显示录音波动的效果, 大小声测试了一下, -30 - 0的取值范围, 5个音量级别(音量的分贝传过来是用IMAudioTool单例传值的, 具体就下一篇说说, 😋)

  • 录音过短模式

低于最短限制(避免误点)

  • 取消录音的模式

向上滑动松开取消,(超出按钮的范围显示这个模式, 没有松开滑入按钮的范围), 恢复正常的显示模式

  • 倒计时模式

当即将要超出录音最大时长的时候, 有倒计时的提示 , demo限制的60, 剩余10秒开始提示

  • 说话过长模式

超出最大限制的时间, 提示这个

具体的实现思路, 因为很多种样式, 每一种提示的控件基本上都不能复用, 所以我就用了好几个View, 显示隐藏来回切换, 控件数量确实挺多的, 暂时没想到其他的好办法, 如果说移除, 需要的时候再去实例化, 会有卡顿, 用内存换速度吧, 这也是最直接的办法了

要注意一点, 当滑动超出范围的时候, 给的是一个松开取消的时候, 当滑入按钮范围的时候, 要判断录音的时长, 看是需要显示哪一种模式, 是正常的模式, 还是倒计时的模式

具体的看代码吧, 比我说的清晰, 我是这么觉得的😀

下一篇说一下, 整个消息的发送过程, 以及本地缓存等等

感谢阅读!!! 感谢阅读!!! 感谢阅读!!!(重要的事情说三遍)😀

前篇
即时通讯整个页面的搭建(一)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,071评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,093评论 4 62
  • 2016.6.2周四。忘记了阳光的温度低着头向前走。 ① 夜晚十点,心情平复下来了。但还是有些不太甘心,一丝丝的心...
    元气满满的慧慧酱阅读 293评论 0 0
  • 听说,这个世界上有三种奇葩:一种是“永远都忘不了的奇葩”;另一种是“一辈子都记不清的奇葩”;而我恰巧就是那两种奇葩...
    李翊轩言阅读 555评论 5 5
  • 喜欢一个人,自己的情绪就会不受控制。 是酒精的作用还是荷尔蒙的冲动 我不敢,不敢靠近你 我怕的是在离你最近的地方又...
    嘉卉卉卉阅读 112评论 0 0