Techniques used: Custom cell, notification mechanism, proxy mode transform
1. Custom cell (custom cell via code)
① first a new class inherits UITableViewCell
② overriding Initwithstyle:reuseidentifier methods
It is only necessary to add all the child controls to be displayed in the Contenview, this step does not normally need to set the property, but if it is some of the child controls some static properties, the word needs a one-time setting, it is set here, when overriding the frameset method in a More dynamic Data fills up and sets
Frame for each child control
③ offers two models
Data model: Storing data
Frame model: Calculates the frame of each space by getting the data model and setting it to ReadOnly
2. Notification mechanism
Thus, we can think that, in a program run, there are many controls to notify the notification center to send notifications, and we can receive the desired notification anywhere, similar to the agent, but the difference between the agent is that the notification is more flexible than the agent, and the notification is a many-to-many relationship, An object can tell n objects what happens, an object can know what happens to n objects, and an agent is a pair of relationships, an object can only tell an object what is going on.
Notification release
-(voidObject:(ID) anobject userInfo: (nsdictionary *) auserinfo; // publish a notification called Aname, AnObject as the publisher of this notification, auserinfo for additional information
Notification monitoring
Notification hubs provides a way to register a listener for a listening notification (in other words, gongzhiyushi the custom notification)
-(void) Addobserver: (IDObject:(ID) anobject; /* *observer: Listener, that is, who wants to receive this notification Aselector: After receiving the notification, callback listener this method, and the notification object as a parameter passed in Aname: the name of the notification. If nil, the listener can receive this notification, regardless of the name of the notification AnObject: notifies the publisher. If both AnObject and Aname are nil, the listener receives all notifications * /
Unregister listener
/*notification hubs does not hold (retain) listener objects, and objects registered in the notification hub must be unregistered before the object is released. Otherwise, the notification hub will still send a message to the listener when the corresponding notification appears again. The Application Crash Notification Center provides a way to unregister listeners because the corresponding listener object has been released*/- (void) Removeobserver: (ID) Observer;- (void) Removeobserver: (ID) Observer Name: (NSString *) aNameObject:(ID) AnObject;//generally unregister before the listener is destroyed (such as by adding the following code to the listener):- (void) Dealloc {//[Super Dealloc]; This sentence needs to be called in non-arc[[Nsnotificationcenter Defaultcenter] removeobserver:self];}
Notification monitoring
object: nil];
3 Proxy Mode
The simple steps are: A protocol that returns the type of ID that implements the protocol, and the method that implements the protocol using the Short Implementation Protocol (delegate)
Difficulty: Custom cell, no change of the chat image stretching, keyboard monitoring
Idea: Create a new model with a computed position, a fill-in data
Create a new view. To display the data inside each cell m
Details:
/* * * Data model * 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
/** * location model * MESSAGEFRAMEDATA.M*/#defineMjtextfont [Uifont systemfontofsize:15]#import "MessageFrameData.h"#import "MessageDataModel.h"@implementationMessageframedata-(void) Setmessage: (Messagedatamodel *) Message {_message=message;//spacingCGFloat padding =Ten;//width of the screenCGFloat Screenw =[UIScreen mainscreen].bounds.size.width; NSLog (@"==========%f", SCREENW);//Time Layout if(!message.hidetime) {CGFloat TimeX=0; CGFloat timey=0; CGFloat Timew=Screenw; CGFloat Timeh= +; _TIMEF=CGRectMake (TimeX, Timey, Timew, Timeh); }//Avatar LayoutCGFloat icony = Cgrectgetmaxy (_TIMEF) +padding; CGFloat iconw= +; CGFloat Iconh= +; CGFloat IconX; if(Message.type = = Messagetypeother) {//someone else sent it.IconX =padding; } Else{//own hair.IconX = screenw-padding-iconw; } _iconf=CGRectMake (IconX, Icony, Iconw, iconh);//BodyCGFloat texty =Icony;//maximum size that can be displayedCgsize textmaxsize = Cgsizemake ( Max, maxfloat);//true size of textCgsize textSize =[self sizeWithText:message.text font:mjtextfont maxsize:textmaxsize];//the size of the final determination;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;}/** * Calculate Text Size * * @param text needs to calculate size * @param font of font text * @param maximum size of maxSize text*/-(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
/** * Custom cell for populating data and setting frame*/#defineMjtextfont [Uifont systemfontofsize:15]#import "QQQViewCellTableViewCell.h"#import "MessageDataModel.h"#import "Uiimage+extension.h"@interfaceQqqviewcelltableviewcell ()//content@property (nonatomic, weak) UIButton *TextView;//Send Time@property (nonatomic, weak) Uiimageview *IconView, @property (nonatomic, weak) UILabel*Timeview;@end@implementationQqqviewcelltableviewcell/** * Rewrite*/-(ID) Initwithstyle: (Uitableviewcellstyle) style Reuseidentifier: (NSString *) Reuseidentifier {//Call the parent class method firstSelf =[Super Initwithstyle:style Reuseidentifier:reuseidentifier]; if(self) {//creation and initialization of sub-spaces//TimeUILabel *timeview =[[UILabel alloc] init]; Timeview.textalignment=Nstextalignmentcenter; Timeview.textcolor=[Uicolor Graycolor]; Timeview.font= [Uifont systemfontofsize: -]; [Self.contentview Addsubview:timeview]; Self.timeview=Timeview;//AvatarUiimageview *iconview =[[Uiimageview alloc] init]; [Self.contentview Addsubview:iconview]; Self.iconview=IconView;//BodyUIButton *textview =[[UIButton alloc] init]; TextView.titleLabel.numberOfLines=0;//Textview.backgroundcolor = [Uicolor graycolor];TextView.titleLabel.font =Mjtextfont; [TextView Settitlecolor:[uicolor Blackcolor] forstate:uicontrolstatenormal];//Set paddingTextview.contentedgeinsets =Uiedgeinsetsmake (textpadding, textpadding, textpadding, textpadding); [Self.contentview Addsubview:textview]; Self.textview=TextView;//set the cell's background colorSelf.backgroundcolor =[Uicolor Clearcolor]; } returnSelf ;}//This is the layout-(void) Setmodel: (Messageframedata *) Model {_model=model; Messagedatamodel*message =Model.message;//TimeSelf.timeView.text =Message.time; Self.timeView.frame=MODEL.TIMEF;//AvatarNSString *icon = (Message.type = = messagetypeother)?@" Other":@"Me"; Self.iconView.image=[UIImage Imagenamed:icon]; Self.iconView.frame=model.iconf;//Body[Self.textview SetTitle:message.text forstate:uicontrolstatenormal]; Self.textView.frame=MODEL.TEXTF;//set the body background image 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{StaticNSString *id =@"Qqmessage"; Qqqviewcelltableviewcell*cell =[TableView Dequeuereusablecellwithidentifier:id]; if(Cell = =Nil) {Cell=[[Qqqviewcelltableviewcell alloc] Initwithstyle:uitableviewcellstyledefault Reuseidentifier:id]; } returncell;}@end
OC Learning path----QQ Chat interface