中山大学数据科学与计算机学院本科生实验报告
(2019年春季学期)
课程名称 | IOS开发 | 任课老师 | 郑贵锋 |
---|---|---|---|
年级 | 16 | 专业(方向) | 软件工程(计算机应用方向) |
学号 | 16340132 | 姓名 | 梁颖霖 |
电话 | 13680473185 | dic0k@qq.com | |
开始日期 | 2019/5/18 | 完成日期 | 2019/5/22 |
一、实验题目
IM聊天工具
二、实现内容
- 处理查看与修改个人详情的区别
- 个人详情页面跳转修改页面
- 读取手机图库修改头像
三、实验结果
1.处理查看与修改个人详情的区别
由于个人详情页面是用于两种情况,一是点击tab进入个人信息,二是在好友列表中点击好友在发起聊天前的个人信息。
好友个人详情页面
用户个人详情页面
这两个页面复用同一个UI,只是最下面的button的字进行判断改变。
我在点击事件跳转前添加判断,你所点击的用户是否是当前登陆的用户。若是则可以修改跳转,若不是则不允许触发点击事件。
self.User == [[UserManager getInstance] getLoginModel]
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// 处理跳转情况
if (self.User == [[UserManager getInstance] getLoginModel]){
NSString* str = self.titleList[indexPath.row];
// 处理头像的情况
if([str isEqualToString:@"头像"]){
// 修改本地显示
[self alterHeadPortrait];
// 上传到云端
}
InfoModifiedViewController *controller = [[InfoModifiedViewController alloc] initWithString:str];
controller.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:controller animated:YES];
}
else{
NSLog(@"不能修改别的用户信息");
}
}
2. 个人详情页面跳转修改页面
在上周完成个人详情页面的前提下,为每个item添加相应的跳转页面。例如点击昵称,则跳转到昵称的修改页面。
如何处理不同的item呢,这里是通过上个页面所传递的参数所决定的。由于点击事件可以获取改item的行号,自然就能获得该行的元素信息。我通过这个信息传递到下一个修改页面,就可以复用其中的代码,唯一的修改也只是hint部分。
// 修改别的文字信息
else{
// 提示信息
NSMutableString* commonHint = @"请输入你要修改的";
// 获取屏幕的宽高
CGRect rect = [[UIScreen mainScreen] bounds];
CGSize size = rect.size;
CGFloat width = size.width;
CGFloat height = size.height;
// 设置背景颜色
self.view.backgroundColor = [UIColor whiteColor];
self.editText = [[UITextField alloc]initWithFrame:CGRectMake(10, 30, width-30, 30)];
self.editText.placeholder = [commonHint stringByAppendingString:self.titleText];
[self.editText setValue:[UIColor grayColor] forKeyPath:@"_placeholderLabel.textColor"];
[self.editText setValue:[UIFont boldSystemFontOfSize:12] forKeyPath:@"_placeholderLabel.font"];
// 下划线
UIView * onLine = [[UIView alloc]initWithFrame:CGRectMake(0,self.editText.frame.size.height-2,self.editText.frame.size.width,2)];
onLine.backgroundColor = [UIColor blackColor];
// 添加导航栏右侧按钮
[self addRightBtn];
[self.editText addSubview:onLine];
[self.view addSubview:self.editText];
}
这里为了确定修改,在导航栏的右侧添加了确定按钮。并对这个确定按钮绑定事件,当点击的时候就会返回修改了的信息到之前的个人详情页面,从而达到修改用户个人详情的功能。
- (void)addRightBtn {
UIBarButtonItem *rightBarItem = [[UIBarButtonItem alloc] initWithTitle:@"确认" style:UIBarButtonItemStylePlain target:self action:@selector(onClickedOKbtn)];
self.navigationItem.rightBarButtonItem = rightBarItem;
}
- (void)onClickedOKbtn {
NSLog(@"onClickedOKbtn");
[self goBackToPersonInfoVCWithNickName:@"test"];
}
- (void) goBackToPersonInfoVCWithNickName:(NSString *) nickName{
InfoViewController *infoVC = [self.navigationController.viewControllers objectAtIndex:self.navigationController.viewControllers.count-2];
//初始化其属性
//传递参数过去
// UserModel user;
// infoVC.User = user;
//使用popToViewController返回并传值到上一页面
[self.navigationController popToViewController:infoVC animated:true];
}
对于性别的修改,由于只有两种情况,所以我们不想让用户来进行输入,避免非法输入,所以我这里利用button group来进行处理,顺便对于这一组件来进行学习。
// 修改性别需要单独处理,使用button来选择而不是输入
if ([self.titleText isEqualToString:@"性别"]) {
[self markArray];
[self btnArray];
[self setupRadioBtnView];
// 添加导航栏右侧按钮
[self addRightBtn];
}
首先是初始化数据
- (NSArray *)markArray {
if (!_markArray) {
NSArray *array = [NSArray array];
array = @[@"男", @"女",@"unknown"];
_markArray = array;
}
return _markArray;
}
- (NSMutableArray *)btnArray {
if (!_btnArray) {
NSMutableArray *array = [NSMutableArray array];
_btnArray = array;
}
return _btnArray;
}
接着定义UI显示
- (void)setupRadioBtnView {
CGFloat UI_View_Width = [UIScreen mainScreen].bounds.size.width;
CGFloat marginX = 15;
CGFloat top = 100;
CGFloat btnH = 30;
CGFloat width = (250 - marginX * 4) / 3;
// 按钮背景
// UIView *btnsBgView = [[UIView alloc] initWithFrame:CGRectMake((UI_View_Width - 250) * 0.5, 50, 250, 300)];
self.view.backgroundColor = [UIColor whiteColor];
// [self.view addSubview:btnsBgView];
// 循环创建按钮
NSInteger maxCol = 2;
for (NSInteger i = 0; i < 2; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor grayColor];
btn.layer.cornerRadius = 3.0; // 按钮的边框弧度
btn.clipsToBounds = YES;
btn.titleLabel.font = [UIFont boldSystemFontOfSize:12];
btn.titleLabel.textColor = [UIColor blackColor];
[btn addTarget:self action:@selector(chooseMark:) forControlEvents:UIControlEventTouchUpInside];
NSInteger col = i % maxCol; //列
CGFloat x = marginX + col * (width + marginX);
NSInteger row = i / maxCol; //行
CGFloat y = top + row * (btnH + marginX);
btn.frame=CGRectMake(x+UI_View_Width/2-width-marginX, y, width, btnH);
[btn setTitle:self.markArray[i] forState:UIControlStateNormal];
[self.view addSubview:btn];
btn.tag = i;
[self.btnArray addObject:btn];
}
// 创建完btn后再判断是否能选择(之前是已经选取过的)
for (UIButton *btn in self.view.subviews) {
if ([@"男" isEqualToString:btn.titleLabel.text]) {
btn.selected = YES;
btn.backgroundColor = [UIColor blueColor];
break;
}
}
}
最后,处理点击事件,判断点击的是什么按钮
- (void)chooseMark:(UIButton *)sender {
NSLog(@"点击了%@", sender.titleLabel.text);
self.selectedBtn = sender;
sender.selected = !sender.selected;
for (NSInteger j = 0; j < [self.btnArray count]; j++) {
UIButton *btn = self.btnArray[j] ;
if (sender.tag == j) {
btn.selected = sender.selected;
} else {
btn.selected = NO;
}
btn.backgroundColor = [UIColor grayColor];
}
UIButton *btn = self.btnArray[sender.tag];
if (btn.selected) {
btn.backgroundColor = [UIColor blueColor];
} else {
btn.backgroundColor = [UIColor grayColor];
}
}
完成这三步,一个可选择并记录历史选择的按钮组就实现完成了。它不仅仅适用于这里,还可以适用于普适性的场景,仅仅需要修改数据的大小即可。
3. 读取手机图库修改头像
修改头像的功能需要访问我们手机的图库,所以首先要判断权限,接着利用UIAlertController弹出提示框,通过点击提示框的相册选择来选择一张图片,最后通过回调函数来获取该图片的信息来对个人详情页面进行改变。
- (void)alterHeadPortrait{
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
// 判断授权情况
if (status == PHAuthorizationStatusRestricted ||
status == PHAuthorizationStatusDenied) {
//无权限 这个时候最好给个提示,用户点击是就跳转到应用的权限设置内 用户动动小手即可允许权限
NSLog(@"no auth");
}
else{
NSLog(@"has auth!!!!!");
}
//初始化提示框
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
//按钮:从相册选择,类型:UIAlertActionStyleDefault
[alert addAction:[UIAlertAction actionWithTitle:@"从相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//初始化UIImagePickerController
UIImagePickerController *PickerImage = [[UIImagePickerController alloc]init];
//获取方式1:通过相册(呈现全部相册),UIImagePickerControllerSourceTypePhotoLibrary
//获取方法2,通过相册(呈现全部图片),UIImagePickerControllerSourceTypeSavedPhotosAlbum
PickerImage.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//允许编辑,即放大裁剪
PickerImage.allowsEditing = YES;
//自代理
PickerImage.delegate = self;
//页面跳转
[self presentViewController:PickerImage animated:YES completion:nil];
}]];
//按钮:取消,类型:UIAlertActionStyleCancel
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
选择完成后的回调函数处理
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *) info{
//定义一个newPhoto,用来存放我们选择的图片。
UIImage *newPhoto = [info objectForKey:@"UIImagePickerControllerEditedImage"];
NSLog(@"success pick");
[self dismissViewControllerAnimated:YES completion:nil];
self.ProfilePicture.image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
[self.tableView reloadData];
// 测试,成功读取图片
// UIImageView *imageView = [[UIImageView alloc] initWithImage:newPhoto];
// [imageView setFrame:CGRectMake(0, 0, newPhoto.size.width, newPhoto.size.height)];
// [self.view addSubview:imageView];
}
四、实验思考及感想
这周首先我们先解决了我们周中遇到了一些问题,讨论了接着需要实现的功能,安排了下分工再进行工作。个人觉得,我们小组的进度还是比较顺利的,基本的业务框架已经搭建完成,接下来的任务就是一步步把它扩充好,填好。我这周继续对个人详情页面来进行修改,包括个人详情用户信息修改的权限判断,信息修改跳转页面的设计,处理button group的ui以及点击逻辑,完成该button group的模块化可复用开发,最后学习了如何访问图片库读取图片。这周的工作内容逐渐多了起来,由于我对ios开发的熟悉的程度也在增加,故可以在有限的开发时间能做更多的事情了。下一步的打算是修改个人详情页面与网络接口连接,据后台处理图片修改的同学说,这里可能会遇到一些问题,故要小心处理参数。