IOS开发笔记(九)——IM聊天工具个人详情页面,自定义tableview的accessaryView
中山大學(xué)數(shù)據(jù)科學(xué)與計算機(jī)學(xué)院本科生實驗報告
(2019年春季學(xué)期)
| 年級 | 16 | 專業(yè)(方向) | 軟件工程(計算機(jī)應(yīng)用方向) |
| 學(xué)號 | 16340132 | 姓名 | 梁穎霖 |
| 電話 | 13680473185 | dic0k@qq.com | |
| 開始日期 | 2019/5/12 | 完成日期 | 2019/5/15 |
一、實驗題目
IM聊天工具
二、實現(xiàn)內(nèi)容
- 個人詳情頁面UI
- 后端接口:獲取聊天消息記錄
三、實驗結(jié)果
聊天消息記錄
1.概述
為了實現(xiàn)聊天工具對話的消息傳遞,這里我們引入了序列號的概念,每一個消息都有它特定的序號,我們根據(jù)這個序列號來確定這個消息是否已經(jīng)發(fā)送,是否已經(jīng)被接受到,是否需要刪除等邏輯。
除此之外,為了實現(xiàn)多用戶間的對話,例如A->B, A->C, B->C,他們之間如何能找到屬于他們各自的信息呢?這里我們利用的是維護(hù)一個消息表,每一條消息都有發(fā)送用戶的id,接受用戶的id,內(nèi)容的id,然后再通過內(nèi)容的id在內(nèi)容表格中找具體的內(nèi)容。
2. URL設(shè)計
獲取用戶之間聊天記錄 /history/personal POST { to: {username} data: {} }在Django的urls.py文件中表現(xiàn)為
urlpatterns = [path('personal', views.personal, name='personal'), ]3. 具體實現(xiàn)
a.從消息表通過用戶名獲取聊天記錄
# 返回聊天記錄 def personal(request, t_username):response = {'state':'fail', 'msg':'no msg'}# 要在登錄狀態(tài)下if 'login_id' not in request.session:response['msg'] = 'no login'return HttpResponse(json.dumps(response), content_type = 'application/json')# 只允許GET方法if request.method != 'POST':response['msg'] = 'wrong method'return HttpResponse(json.dumps(response), content_type = 'application/json')# 查詢的用戶名為空if t_username == '':response['msg'] = 'miss username'return HttpResponse(json.dumps(response), content_type = 'application/json')# 已經(jīng)登錄, 所以拿取用戶信息cur_username = request.session['login_id']# 數(shù)據(jù)庫操作,查詢消息try:# 當(dāng)前用戶發(fā)送給對方的信息cur_to_t_msg = Msg.objects.filter(Username = t_username, From = cur_username)# 對方發(fā)送給當(dāng)前用戶的信息t_to_cur_msg = Msg.objects.filter(Username = cur_username, From = t_username)except Exception as e:response['msg'] = 'db error'return HttpResponse(json.dumps(response), content_type = 'application/json')else:# 根據(jù)兩類消息的ContentID來找出所有content# 這里先假設(shè)所有記錄為文字類型,圖片類型未知結(jié)果,待測試# Content_Text ctArray = []# Content_Image ciArray = []for msg in cur_to_t_msg:if msg.Type == 'text':ctArray.append(Content_Text.objects.filter(Cid = msg.ContentID))elif msg.Type == 'image':ciArray.append(Content_Image.objects.filter(Cid = msg.ContentID))for msg in t_to_cur_msg:if msg.Type == 'text':ctArray.append(Content_Text.objects.filter(Cid = msg.ContentID))elif msg.Type == 'image':ciArray.append(Content_Image.objects.filter(Cid = msg.ContentID))# 根據(jù)ContentID來進(jìn)行append,保證時間有序if len(Content_Text) >= 1:# 序列化,返回多條文字內(nèi)容serialized_obj = serializers.serialize('json', ctArray)response = {'state':'ok', 'msg':'ok', "data":serialized_obj}else:response['msg'] = 'no data'return HttpResponse(json.dumps(response), content_type = 'application/json')具體邏輯
- 定義返回體的內(nèi)容,包括一個state和msg
- 判斷是否已經(jīng)登陸狀態(tài)
- 是,直接返回HttpResponse,告訴前端已經(jīng)登陸,無須注冊
- 否,下一步
- 判斷方法是否為GET
- 判斷查詢的用戶名是否為空
- 獲取用戶登陸的用戶名以及密碼
- 數(shù)據(jù)庫操作
- 通過用戶名獲取當(dāng)前用戶發(fā)送給對方的信息
- 通過用戶名獲取對方發(fā)送給當(dāng)前用戶的信息
- 根據(jù)兩類消息的ContentID來找出所有content
- 根據(jù)ContentID來進(jìn)行append,保證時間有序
- 序列化,返回多條文字內(nèi)容
個人詳情頁面
效果截圖:
個人詳情頁面是使用UITableView來模仿微信聊天工具的詳情所制作的
InfoViewController.h
#import <UIKit/UIKit.h> #import "UserModel.h"NS_ASSUME_NONNULL_BEGIN@interface InfoViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *Birthplace; @property (weak, nonatomic) IBOutlet UILabel *NickName; @property (weak, nonatomic) IBOutlet UILabel *ID; @property (weak, nonatomic) IBOutlet UILabel *Gender; @property (strong, nonatomic) UserModel* User; @property (weak, nonatomic) IBOutlet UIImageView *ProfilePicture;@end首先在.h文件定義所用到的一些屬性,包括用戶名,地區(qū),性別,id號,頭像等,還有一個登陸后的User的信息。
InfoViewController.m
這里首先定義所用到TableView,以及左側(cè)的標(biāo)題列表,右側(cè)的內(nèi)容列表來存儲數(shù)據(jù)
#import "InfoViewController.h"@interface InfoViewController ()<UITableViewDelegate, UITableViewDataSource>@property(nonatomic, strong) UITableView *tableView; @property(nonatomic, strong) NSMutableArray<NSString*> *titleList; @property(nonatomic, strong) NSMutableArray<NSString*> *contentList;@endviewDidLoad函數(shù)中加載數(shù)據(jù)
- 綁定User中的信息到之前定義的屬性當(dāng)中。
- 定義navigationItem的標(biāo)題名。
- 獲取屏幕的寬與高來定義tableview視圖的大小與位置
- 取消tableview默認(rèn)的多余的橫線
加載數(shù)據(jù),定義titleList,contentList
- (void)loadData {self.titleList = [NSMutableArray array];self.contentList = [NSMutableArray array];[self.titleList addObjectsFromArray:[[NSArray alloc] initWithObjects:@"頭像", @"昵稱", @"賬號", @"性別", @"地區(qū)",nil]];[self.contentList addObjectsFromArray:[[NSArray alloc] initWithObjects:@"小豬佩奇", @"Peppa", @"peppy", @"female", @"UK",nil]]; }- 用numberOfSectionsInTableView定義tableview的section數(shù)目
- 用heightForRowAtIndexPath定義tableview每一個cell的高度
根據(jù)不同的行來給每個cell自定義accessoryView, 并綁定不同的數(shù)據(jù)。這里我們第一行是圖片,故需要特殊處理來顯示圖片,而其他行則是顯示內(nèi)容,我這里修改一下它的字體與大小使得更加美觀,對比度更加高。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {NSString *cellID = [NSString stringWithFormat:@"cellID:%zd", indexPath.section];UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];if (nil == cell) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];}// cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;cell.textLabel.text = self.titleList[indexPath.row];cell.textLabel.font = [UIFont fontWithName:@"PingFangSC-Regular" size:18.f];if (indexPath.row != 0){UILabel *rightLabel = [[UILabel alloc]initWithFrame:CGRectMake(0,0,70,55)];rightLabel.text = self.contentList[indexPath.row];rightLabel.font = [UIFont fontWithName:@"PingFangSC-Regular" size:14.f];rightLabel.textColor = [UIColor grayColor];cell.accessoryView = rightLabel;//cell.accessoryView.backgroundColor = [UIColor redColor]; //加上紅色容易看清楚}else{cell.accessoryView = ({UIImageView *imgV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:self.User.ProfilePicture]];CGRect frame = imgV.frame;frame = CGRectMake(0, 0, 100, 55);imgV.frame = frame;[imgV setContentMode:UIViewContentModeScaleAspectFit];imgV;});}return cell; }點擊列表的item時跳轉(zhuǎn)至修改頁面
#pragma mark ------------ UITableViewDelegate ------------------- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {[tableView deselectRowAtIndexPath:indexPath animated:YES];InfoViewController *controller = [[InfoViewController alloc] init];controller.hidesBottomBarWhenPushed = YES;[self.navigationController pushViewController:controller animated:YES]; }用戶退出按鈕綁定事件,這里要與服務(wù)器進(jìn)行交互,刪除之前登陸的session
- (IBAction)logout:(id)sender {NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];NSURLSession *session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:nil delegateQueue:[NSOperationQueue mainQueue]];NSURL *url = [NSURL URLWithString:@"http://118.89.65.154:8000/account/logout/"];NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {if(error == nil) {if(NSClassFromString(@"NSJSONSerialization")) {NSError *e = nil;id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&e];if(e) {NSLog(@"error");}if([object isKindOfClass:[NSDictionary class]]) {NSDictionary *result = object;if([result[@"state"] isEqualToString:@"ok"]) {NSLog(@"logout success");UIStoryboard *indexStoryboard = [UIStoryboard storyboardWithName:@"Index" bundle:nil];[UIApplication sharedApplication].keyWindow.rootViewController = indexStoryboard.instantiateInitialViewController;}else {NSLog(@"logout fail");}}else {NSLog(@"Not dictionary");}}}else {NSLog(@"網(wǎng)絡(luò)異常");}}];[task resume]; }總結(jié)
以上是生活随笔為你收集整理的IOS开发笔记(九)——IM聊天工具个人详情页面,自定义tableview的accessaryView的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于P-CMM
- 下一篇: 计算机组成原理笔记及思维导图汇总附复习建