標籤:
一、知識點:
QQ聊天介面
雙模型的使用(dataModel和frameModel)
UITextField的使用
通知的使用
展開圖片的兩種方法(slicing/image對象的resizeableImageWithCapInsets屬性)
枚舉
方法的抽取(相同的拿出,不同的部分作為參數)
二、設定tableview的基本格式
1)定義tableview基本
numberOfSectionsInTableView:設定塊
numberOfRowsInSection:設定每塊對應的行數
cellForRowAtIndexPath:設定cell樣式
2)cell的重用
設定cell
satic NSString *identifier [email protected]"QQCell";
先從緩衝池中尋找
QQCell *cell =[_tableview dequeuesableCellWithIdentifier:identifier];
如果緩衝池中找不到cell 就建立
if(cell==nil)
{cell =[[QQCell alloc]initWithStyle:UITableViewCellStyleDefault reuserIndentiier:identifier];}
3)設定自訂的cell格式(注意為什麼訊息框是button:因為既可以設定文本,又可以設定圖片)
a、定義需要用到的屬性及樣式
@property(nonatomic,weak)UILabel *timeLabel;
@property(nonatomic,weak)UIButton *textButton;
@property(nonatomic,weak)UIImageView *iconImage;
b、定義初始化方法,注意與viewController中cell建立時調用的方法要一致
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if(self =[super initWithStyle:style reuseIdentifier:reuseIdentifier]{
[self setupUI];//在內部設定button、label之類的樣式
}}return self;
c、雙模型(在懶載入中將資料模型傳遞給frame模型:原因:
1、懶載入中,方法只需要執行一次
2、行高rowheight 方法必須在cell方法調用前調用,所以要在cell中實現frame的計算,傳遞出來順序是有問題的
傳遞方式: 在frameModel中定義QQModel這一屬性
a、定義model屬性
@class QQModel;
@property (nonatomic ,strong) QQModel *qqModel;
b、在懶載入中實現賦值
QQModel *model =[QQModel QQmodelWithDictionary:dict];
QQFrameModel *frameModel =[QQFrameModel alloc]init];
frameModel.qqModel =model;//傳遞成功
c、把frameModel的值傳入dataArray數組中,因為這會frameModel中既有(資料model也包含各個控制項的Frame)
[_dataArray addObject:frameModel];
d、如何根據文本資料內容,設定frame
1)、設定最大可變動地區(如果無限制則:MAXFLOAT)
CGSize maxArea =CGSizeMake(textMaxA,MAXFLOAT);
2)、設定屬性字典(注意屬性字型大小的設定一定要和原先控制項中字型大小一致,否則,可能文本中以省略符號帶過)
NSDictionary *dict [email protected]{NSFontAttributeName:[UIFont systemFontOfSize:17};
3)、設定對象資料的真實大小boundingRectWithSize
CGSize RealSize =[_qqModel.text boundingRectWithSize :maxArea options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context :nil].size;
e、在cell的設定類中調用frameModel和資料模型並設定
1)重寫FrameModel的set方法:
@property(nonatomic,strong) QQFrameModel *frameModel;
-(void)setFrameModel:(QQFrameModel *)frameModel{
2)必須對模型進行執行個體化
_frameModel =frameModel;
3)設定模型中的資料和Frame
}
怎麼擷取qqModel
#import “QQModel.h”
QQModel *qqModel =_frameModel.qqModel;
f、代碼實現圖片展開
/**
1、擷取圖片
2、設定展開 線條構成的中心地區(地區越小越好,所以將寬高都設成其中心線)
3、調用image對象的resizableImageWithCapInSets屬性
*/
UIImage *image =[UIImage imageNamed:imageName];
CGFloat *halfWidth =image.size.width/2;
CGFloat *halfHeight =image.size.height/2;
UIImage *resizeImage =[image resizableImageWithCapInsets:UIEdgeInsetsMake(halfHeight,halfWidth,halfHeight,halfWidth) resizingMode:UIImageResizingModeStretch];
g、注意圖片展開之後,文本可能不在圖片內部,可以通過增加button的frame大小,同時設定文本的那邊距(contentEdgeInsets UIEdgeInsetsMake)
textButton.contentEdgeInsets =UIEdgeInsetsMake(20,20,20,20);
h、設定行高
heightForRowAtIndexPath
QQ FrameModel *frameModel =self.dataArray[indexPath.row];
return frameModel.cellHeight
三、比較時間(兩兩比較,同一時間內的label只顯示一遍,可以知道,只要比較一次,而且又要獲得上一次的時間,最好在懶載入中實現)
/**
0、在qqModel中設定一個HiddenTimeLabel屬性 儲存比較完的結果
1、取出上一次的資料
2、進行比較,如果一樣的話,就往qqModel 中傳入HiddenTimeLabel=YES
*/
@property (nonatomic,assign,getter = isHiddenTimeLabel) BOOL HiddenTimeLabel;
QQFrameModel *latFrameModel =self.dataArray.lastObject;
if([lastFrameModel.qqModel.time isEqualToString :frameModel.qqModel.time])
{
qqModel.HiddenTimeLabel=YES;
}
調用:
_timeLabel.hidden =qqModel.isHiddenTimeLabel;(在hidden屬性中直接調用重寫的get方法即可)
四、補充使用枚舉(內部的值類別,枚舉的值名稱,預設從0開始)
typedef NS_ENUM(NSInteger,QQUserType)
{
QQUserTypeOther=0;
QQuserTypeMe,
};
枚舉的好處:將無意義的數字轉化成有意義的字元,增加代碼可讀性
五、設定底部的彈框(瞭解textField屬性和通知概念)
五.1 TextField 的使用
[email protected]"預留位置"
UIView *left =[[UIView alloc]initWithFrame:CGRectMake(100, 0, 10, 10)];
left.backgroundColor=[UIColor orangeColor];
text.leftView=left;
text.leftViewMode = UITextFieldViewModeAlways;
(添加leftview的時候必須要設定UITextFieldViewMode否則無法顯示
leftview/rightview/leftViewMode/rightViewMode
密碼:
text.secureTextEntry=YES;
text.cleanButtonMode =UITextFieldViewModeWhileEditing;
五、2)通知的使用
/**
1、註冊監聽者
2、通知中樞發布通知
3、將銷毀的監聽者移除監聽
*/
1
/**
addObserver: 監聽對象
selector:監聽對象收到通知之後調用的方法
name:通知的名稱
object: 通知的發行者
*/
[[NSNotificationCenter defaultCenter] addObserver:ZhangSan selector:@selector(recieveNotification:) name:@"HuoYing" object:souhuHuoYing];
2
/**
接受通知之後,要執行的方法
*/
-(void) recieveNotification:(NSNotification *)noti
{
NSDictionary *c = noti.userInfo;
Company *company = c[@"company"];
NSLog(@"%@ 訂閱了 %@公司的 %@視頻已經更新了",self.personname,company.companyname,company.moviename);
// NSLog(@"%@",noti);
}
3
-(void) dealloc
{
[[NSNotificationCenter defaultCenter]removeObserver:self.personname];
}
五、3)設定鍵盤監聽,通過監聽傳遞出的通知,改變底部輸入框的frame和tableview的frame
1、// 添加監聽, 鍵盤即將隱藏的時候, 調用
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillDisAppear:)
name:UIKeyboardWillHideNotification
object:nil];
調用的監聽通知名稱包括:UIKeyboardWillHideNotification /鍵盤即將隱藏的通知名
name:UIKeyboardWillChangeFrameNotification/鍵盤隱藏或出現的通知名
UIKeyboardWillShowNotification/鍵盤出現的通知名
2、收到通知訊息時要執行的動畫:(UIView animateWithDuration)
[UIView animateWithDuration:interval animations:^{
self.view.transform = CGAffineTransformMakeTranslation(0, (keyboardEndY - keyboardBeginY));
}];
3、使用者如果滾動tableview的時候,或者使用者輸入完成按return的時候,鍵盤都需要消失
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
// 撤銷textField 的第一響應者身份
[_textField resignFirstResponder];
}
4、預設的時候,tableview都應該滾動到最後一行(UITableView scrollToRowAtIndexPath)
- (void)scrollToBottom {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.dataArray.count - 1 inSection:0];
[_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
5、既然是聊天框,那麼cell就不應該有被選中時候的顏色(selectionStyle)
// 選中cell後不改變顏色
cell.selectionStyle = UITableViewCellSelectionStyleNone;
6、撤銷監聽
#warning 一定不要忘記移除監聽者
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
六、設定時間格式
/**
1、取出時間(NSDate date)
2、初始化格式NSDateFormatter (NASDateFormatter) formatter.dateformat(屬性)
3、日期轉字元 formatter stringFromDate:currentDate
*/
// 取出當前的時間
NSDate *currentDate = [NSDate date];
// 設定時間的格式
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 時間格式
// yyyy-MM-dd HH:mm:ss 時間格式
formatter.dateFormat = @"HH:mm";
NSString *dateString = [formatter stringFromDate:currentDate];
七、通知和代理的區別
共同:都可以傳遞訊息
區別:代理是一對一傳遞,通知是多對多,可以有多個訊息發行者和多個訊息接收者
例如,代理可以知道textfiled什麼時候開始輸入值,什麼時候結束輸入值,但是像鍵盤這種彈入彈出它的時間都是不可控的,需要即時監測這個就需要通知中樞發布訊息。
Objective-c——UI基礎開發第八天(QQ聊天介面)