需求详解:实际开发中,后期优化的时候可能会有这样的优化需求:聊天输入框保存之前输入的文字,提高用户体验。好的经历。在聊天模块中,用户可能在输入框中输入了一些字符,但是点击退出聊天却没有点击发送,或者点击用户头像确认用户信息,或者比如需要将另一个好友的ID发送给好友并且不得不暂时退出当前聊天的好友聊天界面跳转到另外一个界面找ID。但是,当前的聊天输入框已经输入了好几个字符。当然,用户退出后并不想删除之前输入的文本。所以这里需要暂时保存用户输入但没有发送出去的字符串。不过还是要满足1的要求,要彻底杀掉或者彻底退出应用,需要清除临时保存的字符串。2.发送出去后,委托前临时保存的字符串一定要require。开始:一开始对这部分逻辑的实现没有很好的想法。我只想到局部序列化,但实际上这不是最好的主意,因为局部序列化在这里有点小题大做了,其实只要用一个全局静态变量的字典就可以了。具体实现的逻辑,我也阅读研究了Coding项目的实现。毕竟这个项目是一个比较成熟的项目,聊天模块也做得很好,所以学习别人的想法就是所谓的站在巨人的肩膀上。哦很好。所以下面我直接解读本聊天模块内容保存中Coding源码(学习Coding-iOS开源项目日志(一))的逻辑,自己开发的项目就不说了。1.首先声明全局静态变量。在Coding中,inputStrDict用于存放输入框的字符串。我不知道inputMediaDict实际上存储了什么。应该是像media这样的元素:2.然后把很多逻辑封装在这个UIMessageInputView类中,方法不需要是public的,可以充分利用UIMessageInputView活动循环的逻辑。#pragmamarkrememberinput-(NSMutableDictionary*)shareInputStrDict{if(!_inputStrDict){_inputStrDict=[[NSMutableDictionaryalloc]init];}return_inputStrDict;}-(NSMutableDictionary*)shareInputMediaDict{if(!_inputMediaDict){_inputMediaDict=[[NSMutableDictionary]indictionary];}return_inputMediaDict;}-(NSString*)inputKey{NSString*inputKey=nil;if(_contentType==UIMessageInputViewContentTypePriMsg){inputKey=[NSStringstringWithFormat:@"privateMessage_%@",self.toUser.global_key];}else{if(_commentOfId){switch(_contentType){caseUIMessageInputViewContentTypeTweet:inputKey=[NSStringstringWithFormat:@"tweet_%@_%@",_commentOfId.stringValue,_toUser.global_key.length>0?_toUser.global_key:@""];break;caseUIMessageInputViewContentTypeTopic:inputKey=[NSStringstringWithFormat:@"topic_%@_%@",_commentOfId.stringValue,_toUser.global_key.length>0?_toUser.global_key:@""];break;caseUIMessageInputViewContentTypeTask:inputKey=[NSStringstringWithFormat:@"task_%@_%@",_commentOfId.stringValue,_toUser.global_key.length>0?_toUser.global_key:@""];break;default:break;}}}returninputKey;}-(NSString*)inputStr{NSString*inputKey=[selfinputKey];if(inputKey){DebugLog(@"inputStr_get:%@",[[selfshareInputStrDict]objectForKey:inputKey]);return[[selfshareInputStrDict]objectForKey:inputKey];}returnnil;}-(void)deleteInputData{NSString*inputKey=[selfinputKey];DebugLog(@"inputKey_delegate:%@",inputKey);if(inputKey){[[selfshareInputStrDict]removeObjectForKey:inputKey];[[selfshareInputMediaDict]removeObjectForKey:inputKey];}}-(void)saveInputStr{NSString*inputStr=_inputTextView.text;NSString*inputKey=[selfinputKey];DebugLog(@"inputKey_save:%@",inputKey);if(inputKey&&inputKey.length>0){if(inputStr&&inputStr.length>0){[[selfshareInputStrDict]setObject:inputStrforKey:inputKey];}else{[[selfshareInputStrDict]removeObjectForKey:inputKey];}}}-(void)saveInputMedia{NSString*inputKey=[selfinputKey];if(inputKey&&inputKey.length>0){if(_mediaList.count>0){[[selfshareInputMediaDict]setObject:_mediaListforKey:inputKey];}else{[[selfshareInputMediaDict]removeObjectForKey:inputKey];}}}-(NSMutableArray*)inputMedia{NSString*inputKey=[selfinputKey];if(inputKey){return[[selfshareInputMediaDict]objectForKey:inputKey];}returnil;}-(void)setToUser:(User*)toUser{_toUser=toUser;NSString*inputStr=[selfinputStr];if(_inputTextView){if(_contentType!=UIMessageInputViewContentTypePriMsg){self.placeHolder=_toUser?[NSStringstringWithFormat:@”回复%@",_toUser.name]:@"写评论";}else{self.placeHolder=@"请输入私信内容";}_inputTextView.selectedRange=NSMakeRange(0,_inputTextView.text.length);[_inputTextViewinsertText:inputStr?inputStr:@""];_mediaList=[selfinputMedia];[selfmediaListChenged];}以上无非是将聊天对象的名字拼接成一个键值,然后将当前输入框的字符串对应存入全局静态字典,然后fetching,删除的几种方法3.看这几个方法调用的地方:保存方法,放到frame重写方法中,因为输入框会随着键盘的真实和隐藏切换frame,但是我公司项目的聊天模块启动是开发的由我的同事。我发现他是用Masonry的布局代码来改变输入框的位置的。选择布局约束就意味着放弃框架,所以在哪里调用save方法要根据实际需要和实际编码来实现。另外,其实一开始开发这个输入框的时候,可以考虑一下它的运行周期:开始编辑->编辑->结束编辑。这些操作周期可以实现自己的方法,就像控制器的生命周期一样。总之思路很多,做好了才能实现好管理和维护的逻辑。然后想办法删除。删除的方式是将字符串放在字符串的最前面,因为已经发送过了,可以删除保存在字典中的元素。另外,在创建key的时候,key字符串依赖于当前的聊天对象,因为当前输入框的内容必须和当前的好友对象一一对应,所以我无法保存对应的输入框内容当前好友和跳转到其他好友再次有相同内容。因此需要根据当前好友的字符串来确定key值,所以在Coding源码中重写了ToUser属性的set方法:
