G17

中山大学数据科学与计算机学院本科生实验报告

(2019年秋季学期)

课程名称手机平台应用开发任课老师郑贵锋
年级2019级专业(方向)软件工程计应方向
学号17343123姓名吴宗原
电话15013029107Email1120902512@qq.com
开始日期2019.12完成日期2020.01

一、实验题目

期末项目——xxx


二、实现内容

本人负责的应用的实现部分:

1.个人信息页面的UI优化
2.导航栏控制的三个页面的手势滑动(左右滑动切换页面)的功能
3.底部导航栏的实现(点击底部导航栏切换不同页面)
4.整合代码,协助完成测试

三、实验结果

(1)实验截图

在这里插入图片描述

在这里插入图片描述

(2)实验步骤以及关键代码

个人信息界面的UI
个人信息界面有以下组件:一个旋转的个人头像、一个Segmented控件引导的ViewController子界面,子界面中有个人的详细信息以及一个退出登录的Cell。
1.旋转头像的实现函数(UIButton *)rotate360DegreeWithImageView:(UIButton *)imageView

-(UIButton *)rotate360DegreeWithImageView:(UIButton *)imageView{
    CABasicAnimation *animation = [ CABasicAnimation animationWithKeyPath: @"transform" ];
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    //围绕Z轴旋转,垂直与屏幕
    animation.toValue = [ NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI/2.0, 0.0, 0.0, 1.0) ];
    animation.duration = 3;
    //旋转效果累计,先转180度,接着再旋转180度,从而实现360旋转
    animation.cumulative = YES;
    animation.repeatCount = MAXFLOAT;
    CGRect imageRrect = CGRectMake(0, 0,imageView.imageView.frame.size.width, imageView.imageView.frame.size.height);
    UIGraphicsBeginImageContext(imageRrect.size);
    //在图片边缘添加一个像素的透明区域,去图片锯齿
    [imageView.currentImage drawInRect:CGRectMake(1,1,imageView.imageView.frame.size.width-2,imageView.imageView.frame.size.height-2)];
    [imageView setImage: UIGraphicsGetImageFromCurrentImageContext() forState:UIControlStateNormal];
    UIGraphicsEndImageContext();
    [imageView.layer addAnimation:animation forKey:nil];

    return imageView;
}

2.子界面的信息 (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *cellID=@"ProfileViewCell";
    
    ProfileViewCell *cell= [tableView cellForRowAtIndexPath:indexPath];
    
    if(nil==cell){
        cell=[[ProfileViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
    }
    cell.backgroundColor=[UIColor clearColor];
    cell.textLabel.backgroundColor=[UIColor clearColor];
    if(indexPath.row==4)
        cell.textLabel.text=@"退出登录";
    else cell.textLabel.text=_details[indexPath.row+1];
    cell.textLabel.textAlignment=NSTextAlignmentCenter;
    //UIImageView *IconView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"背景1.jpeg"]];
    cell.imageView.image=[UIImage imageNamed:dataList[indexPath.row]];
    /*
    cell.detailTextLabel.text = details[indexPath.row];
    cell.detailTextLabel.textColor=[UIColor blackColor];
    cell.textLabel.textAlignment = NSTextAlignmentLeft;
    */
    
    cell.layer.masksToBounds = NO;
    cell.layer.cornerRadius = 8.0;
    return cell;
}

3.毛玻璃效果

UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
    UIVisualEffectView *visualView = [[UIVisualEffectView alloc]initWithEffect:blurEffect];
    visualView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);;
    [self.view addSubview:visualView];

底部导航栏的相关函数,包括滑动动画的实现以及自定义导航栏。
1.滑动动画相关

@interface TransitionController()

@property (nonatomic, weak) id<UIViewControllerContextTransitioning> transitionContext;

@property (nonatomic, strong, readonly) UIPanGestureRecognizer *gestureRecognizer;

@property (nonatomic, readwrite) CGPoint initialTranslationInContainerView;

@end

@implementation TransitionController

- (instancetype)initWithGestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer{
    self = [super init];
    if (self){
        _gestureRecognizer = gestureRecognizer;
        [_gestureRecognizer addTarget:self action:@selector(gestureRecognizeDidUpdate:)];
    }
    return self;
}

- (instancetype)init{
    @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Use -initWithGestureRecognizer:" userInfo:nil];
}

- (void)dealloc{
    [self.gestureRecognizer removeTarget:self action:@selector(gestureRecognizeDidUpdate:)];
}

- (void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    self.transitionContext = transitionContext;
    self.initialTranslationInContainerView = [self.gestureRecognizer translationInView:transitionContext.containerView];
    [super startInteractiveTransition:transitionContext];
}

- (CGFloat)percentForGesture:(UIPanGestureRecognizer *)gesture{
    UIView *transitionContainerView = self.transitionContext.containerView;
    CGPoint translation = [gesture translationInView:gesture.view.superview];
    if ((translation.x > 0.f && self.initialTranslationInContainerView.x < 0.f) ||
        (translation.x < 0.f && self.initialTranslationInContainerView.x > 0.f)){
        return -1.f;
    }
    return fabs(translation.x)/CGRectGetWidth(transitionContainerView.bounds);
}

- (void)gestureRecognizeDidUpdate:(UIScreenEdgePanGestureRecognizer *)gestureRecognizer{
    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan:
            break;
        case UIGestureRecognizerStateChanged:
            if ([self percentForGesture:gestureRecognizer] < 0.f) {
                [self cancelInteractiveTransition];
                [self.gestureRecognizer removeTarget:self action:@selector(gestureRecognizeDidUpdate:)];
            }
            else {
                [self updateInteractiveTransition:[self percentForGesture:gestureRecognizer]];
            }
            break;
        case UIGestureRecognizerStateEnded:
            if ([self percentForGesture:gestureRecognizer] >= 0.4f){
                [self finishInteractiveTransition];
            }
            else{
                [self cancelInteractiveTransition];
            }
            break;
        default:
            [self cancelInteractiveTransition];
            break;
    }
}

@end
@implementation TransitionAnimation

- (instancetype)initWithTargetEdge:(UIRectEdge)targetEdge{
    self = [self init];
    if (self) {
        _targetEdge = targetEdge;
    }
    return self;
}

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 0.35;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    
    CGRect fromFrame = [transitionContext initialFrameForViewController:fromViewController];
    CGRect toFrame = [transitionContext finalFrameForViewController:toViewController];
    
    CGVector offset;
    if (self.targetEdge == UIRectEdgeLeft){
        offset = CGVectorMake(-1.f, 0.f);
    }
    else if (self.targetEdge == UIRectEdgeRight){
        offset = CGVectorMake(1.f, 0.f);
    }
    else{
        NSAssert(NO, @"targetEdge must be one of UIRectEdgeLeft, or UIRectEdgeRight.");
    }
    
    fromView.frame = fromFrame;
    toView.frame = CGRectOffset(toFrame,
                                toFrame.size.width * offset.dx * -1,
                                toFrame.size.height * offset.dy * -1);
    
    [transitionContext.containerView addSubview:toView];
    NSTimeInterval transitionDuration = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:transitionDuration animations:^{
        fromView.frame = CGRectOffset(fromFrame,
                                      fromFrame.size.width * offset.dx,
                                      fromFrame.size.height * offset.dy);
        toView.frame = toFrame;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
}

@end

2.自定义TabBarViewController

@interface TabBarViewController ()<UITabBarControllerDelegate>

@property(nonatomic, strong)UIPanGestureRecognizer *panGestureRecognizer;

@end

@implementation TabBarViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.delegate = self;
    self.selectedIndex = 0;
    [self.view addGestureRecognizer:self.panGestureRecognizer];

    NSArray<UIColor *> *colors = @[[UIColor orangeColor], [UIColor redColor], [UIColor blueColor], [UIColor yellowColor], [UIColor purpleColor]];
    NSMutableArray *vcs = [[NSMutableArray alloc] init];
    for (UIColor *color in colors) {
        ViewController *vc = [[ViewController alloc]init];
        vc.view.backgroundColor = color;
        [vcs addObject:vc];
    }
    self.viewControllers = vcs;
    
    for (int i = 0; i < self.tabBar.items.count; i ++) {
        NSDictionary *dic = @{NSForegroundColorAttributeName: [UIColor colorWithRed:0.451 green:0.553 blue:0.584 alpha:1.00]};
        NSDictionary *selecteddic = @{NSForegroundColorAttributeName: [UIColor colorWithRed:0.384 green:0.808 blue:0.663 alpha:1.00]};
        
        UITabBarItem *item = [self.tabBar.items objectAtIndex:i];
        [item setTitleTextAttributes:dic forState:UIControlStateNormal];
        [item setTitleTextAttributes:selecteddic forState:UIControlStateSelected];
        
        switch (i) {
            case 0:
                item.title = @"壹";
                break;
            case 1:
                item.title = @"贰";
                break;
            case 2:
                item.title = @"叁";
                break;
            case 3:
                item.title = @"肆";
                break;
            case 4:
                item.title = @"伍";
                break;
            default:
                break;
        }
    }
}

- (UIPanGestureRecognizer *)panGestureRecognizer{
    if (_panGestureRecognizer == nil){
        _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognizer:)];
    }
    return _panGestureRecognizer;
}

- (void)panGestureRecognizer:(UIPanGestureRecognizer *)pan{
    if (self.transitionCoordinator) {
        return;
    }
    
    if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged){
        [self beginInteractiveTransitionIfPossible:pan];
    }
}

- (void)beginInteractiveTransitionIfPossible:(UIPanGestureRecognizer *)sender{
    CGPoint translation = [sender translationInView:self.view];
    if (translation.x > 0.f && self.selectedIndex > 0) {
        self.selectedIndex --;
    }
    else if (translation.x < 0.f && self.selectedIndex + 1 < self.viewControllers.count) {
        self.selectedIndex ++;
    }
}

- (id<UIViewControllerAnimatedTransitioning>)tabBarController:(UITabBarController *)tabBarController animationControllerForTransitionFromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
        NSArray *viewControllers = tabBarController.viewControllers;
        if ([viewControllers indexOfObject:toVC] > [viewControllers indexOfObject:fromVC]) {
            return [[TransitionAnimation alloc] initWithTargetEdge:UIRectEdgeLeft];
        }
        else {
            return [[TransitionAnimation alloc] initWithTargetEdge:UIRectEdgeRight];
        }

}

- (id<UIViewControllerInteractiveTransitioning>)tabBarController:(UITabBarController *)tabBarController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController{
    if (self.panGestureRecognizer.state == UIGestureRecognizerStateBegan || self.panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
        return [[TransitionController alloc] initWithGestureRecognizer:self.panGestureRecognizer];
    }
    else {
        return nil;
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end

四、个人总结与个人贡献评分

个人感觉自己在这次项目中的贡献不算太多,完成过程还是比较快的,完成的部分主要是一些前端的内容,包括TabBar和个人信息的界面,后端的内容并没有涉及。但是还是感觉巩固了很多学习到的东西,包括如何从服务器返回的json包中提取出想要的信息,一些自定义动画、自定义组件的实现等内容。完成之后也是整合了其他同学的代码,协助写完后端的同学测试了通信的有效性,录制了视频。
个人贡献评分:85


五、实验思考及感想

这次的项目认识到了一个软件开发的过程中需要的知识还是很多的,包括UI设计、前后端开发、软件测试等多个方面,一个人是没办法面面俱到的,同时体现了多人开发时协作交流的重要性。这次项目还是尽可能把这学期学到的很多Objective-c的知识用上去了,也去了解了前后端交互的一些调用以及整个流程,总的来说还是获益匪浅。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值