IOS开发笔记(九)——IM聊天工具个人详情页面,自定义tableview的accessaryView
中山大學數據科學與計算機學院本科生實驗報告
(2019年春季學期)
| 年級 | 16 | 專業(方向) | 軟件工程(計算機應用方向) |
| 學號 | 16340132 | 姓名 | 梁穎霖 |
| 電話 | 13680473185 | dic0k@qq.com | |
| 開始日期 | 2019/5/12 | 完成日期 | 2019/5/15 |
一、實驗題目
IM聊天工具
二、實現內容
- 個人詳情頁面UI
- 后端接口:獲取聊天消息記錄
三、實驗結果
聊天消息記錄
1.概述
為了實現聊天工具對話的消息傳遞,這里我們引入了序列號的概念,每一個消息都有它特定的序號,我們根據這個序列號來確定這個消息是否已經發送,是否已經被接受到,是否需要刪除等邏輯。
除此之外,為了實現多用戶間的對話,例如A->B, A->C, B->C,他們之間如何能找到屬于他們各自的信息呢?這里我們利用的是維護一個消息表,每一條消息都有發送用戶的id,接受用戶的id,內容的id,然后再通過內容的id在內容表格中找具體的內容。
2. URL設計
獲取用戶之間聊天記錄 /history/personal POST { to: {username} data: {} }在Django的urls.py文件中表現為
urlpatterns = [path('personal', views.personal, name='personal'), ]3. 具體實現
a.從消息表通過用戶名獲取聊天記錄
# 返回聊天記錄 def personal(request, t_username):response = {'state':'fail', 'msg':'no msg'}# 要在登錄狀態下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')# 已經登錄, 所以拿取用戶信息cur_username = request.session['login_id']# 數據庫操作,查詢消息try:# 當前用戶發送給對方的信息cur_to_t_msg = Msg.objects.filter(Username = t_username, From = cur_username)# 對方發送給當前用戶的信息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:# 根據兩類消息的ContentID來找出所有content# 這里先假設所有記錄為文字類型,圖片類型未知結果,待測試# 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))# 根據ContentID來進行append,保證時間有序if len(Content_Text) >= 1:# 序列化,返回多條文字內容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')具體邏輯
- 定義返回體的內容,包括一個state和msg
- 判斷是否已經登陸狀態
- 是,直接返回HttpResponse,告訴前端已經登陸,無須注冊
- 否,下一步
- 判斷方法是否為GET
- 判斷查詢的用戶名是否為空
- 獲取用戶登陸的用戶名以及密碼
- 數據庫操作
- 通過用戶名獲取當前用戶發送給對方的信息
- 通過用戶名獲取對方發送給當前用戶的信息
- 根據兩類消息的ContentID來找出所有content
- 根據ContentID來進行append,保證時間有序
- 序列化,返回多條文字內容
個人詳情頁面
效果截圖:
個人詳情頁面是使用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文件定義所用到的一些屬性,包括用戶名,地區,性別,id號,頭像等,還有一個登陸后的User的信息。
InfoViewController.m
這里首先定義所用到TableView,以及左側的標題列表,右側的內容列表來存儲數據
#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函數中加載數據
- 綁定User中的信息到之前定義的屬性當中。
- 定義navigationItem的標題名。
- 獲取屏幕的寬與高來定義tableview視圖的大小與位置
- 取消tableview默認的多余的橫線
加載數據,定義titleList,contentList
- (void)loadData {self.titleList = [NSMutableArray array];self.contentList = [NSMutableArray array];[self.titleList addObjectsFromArray:[[NSArray alloc] initWithObjects:@"頭像", @"昵稱", @"賬號", @"性別", @"地區",nil]];[self.contentList addObjectsFromArray:[[NSArray alloc] initWithObjects:@"小豬佩奇", @"Peppa", @"peppy", @"female", @"UK",nil]]; }- 用numberOfSectionsInTableView定義tableview的section數目
- 用heightForRowAtIndexPath定義tableview每一個cell的高度
根據不同的行來給每個cell自定義accessoryView, 并綁定不同的數據。這里我們第一行是圖片,故需要特殊處理來顯示圖片,而其他行則是顯示內容,我這里修改一下它的字體與大小使得更加美觀,對比度更加高。
- (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時跳轉至修改頁面
#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]; }用戶退出按鈕綁定事件,這里要與服務器進行交互,刪除之前登陸的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(@"網絡異常");}}];[task resume]; }總結
以上是生活随笔為你收集整理的IOS开发笔记(九)——IM聊天工具个人详情页面,自定义tableview的accessaryView的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于P-CMM
- 下一篇: 计算机组成原理笔记及思维导图汇总附复习建