Uber车辆移动动效实现

作者: xiaoliuTX_iOS | 来源:发表于2017-01-17 20:13 被阅读2401次

    项目中有需求需要实现车辆在地图上的行车轨迹,就像uber上小车移动的动效一样。刚接到需求时以为很简单,timer获取到车辆的经纬度及车头方向后两次tansform仿射变换,先transform方向动画再transform移动动画。
    想向是美好的,实际中发现以下问题:

    1. transform 旋转角度后坐标系发生变化了在这个基础上再进行位置的transform会有很大的偏移;具体参考iOS中的图形变换
    2. 百度地图在移动显示区域重绘时会将之前的annotationview的状态清除,设置小车annotationview的tansformmakerotate后移动地图又还原成了原来的初始状态
    3. 将coordinate转换成百度地图坐标后再进行位移动画,动画结束后改变annotation的coordinate发现会有一点小偏移。

    思考无果情况下决定利用Reveal查看下Uber的页面元素一探究竟:


    image

    可以发现,Uber的实现是在ONEDriverAnnotationView下自己添加了一个子的UIImageView,设置车辆方向时针对子UIImageView进行旋转,位移动画交由ONEDriverAnnotationView实现。
    代码如下:

    // 设置自定义标注样式
    - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation {
        //设置司机标注视图
        if ([annotation.title isEqualToString:kBusAnnotaionText]) {
            NSString *AnnotationViewID = @"renameMark";
            //DuMapBusAnnotationView继承自BMKMapAnnotationView,添加busImageView属性
            DuMapBusAnnotationView *annotationView = (DuMapBusAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
            if (annotationView == nil)
            {
                annotationView = [[DuMapBusAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
                annotationView.image = [UIImage imageNamed:@"bus_backView"];
                annotationView.busImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(annotationView.frame), CGRectGetHeight(annotationView.frame))];
                // bus_backView图片与bus图片大小一样,但内容为全透明
                annotationView.busImageView.image = [UIImage imageNamed:@"bus"];
                [annotationView addSubview:annotationView.busImageView];
                annotationView.canShowCallout = NO;
                // 提升annotationview层级防止被遮挡
                [annotationView.superview bringSubviewToFront:annotationView];
            }
            self.busAnnotationView = annotationView;
            return annotationView;
        }
     
        return nil;
    }
    
    // 更新车辆位置动画,在定时器中重复调用
    - (void)updateBusLocation {
        //移除旧的
        if (_busLatitude <= 0 || _busLongitude <= 0) {
            [_DUMapView removeAnnotation:_busWhereAnnotaion];
            return;
        }
        if (![_DUMapView.annotations containsObject:_busWhereAnnotaion]) {
            [_DUMapView  addAnnotation:_busWhereAnnotaion];
            CLLocationCoordinate2D coor;
            coor.latitude = _busLatitude;
            coor.longitude = _busLongitude;
            _busWhereAnnotaion.coordinate = coor;
        }    
        CLLocationCoordinate2D coor;
        coor.latitude = _busLatitude;
        coor.longitude = _busLongitude;
        
        [UIView animateWithDuration:0.25 animations:^{
            // 对子视图busImageView进行旋转动画
            self.busAnnotationView.busImageView.transform = CGAffineTransformMakeRotation(self.course*M_PI/180);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:2.5 animations:^{
                // 更新coordinate即可进行位移动画
                self.busWhereAnnotaion.coordinate = coor;
            } completion:^(BOOL finished) {
                 // do something else
            }];
        }];
    }
    
    

    Demo下载 2016.2.6

    相关文章

      网友评论

      • jayZhou1991:小车位移的动画 没有效果
      • 0271fb6f797c:这个demo是什么?跟车辆移动好像不太一样啊?
        xiaoliuTX_iOS:不好意思搞错链接了https://github.com/xiaoliuTX/Copy-Uber-Car-Moving-Animation
      • 刺骨寒:有demo 吗 ? 想研究研究一下
        xiaoliuTX_iOS:Demo已上传
      • xxttw:牛叉
        xiaoliuTX_iOS:中间走了不少弯路,想着将经纬度转换为地图坐标后对坐标动画,用属性记录每次的angle然后在地图重绘时重新设置一次标注的transform。结果效果总是不尽人意

      本文标题:Uber车辆移动动效实现

      本文链接:https://www.haomeiwen.com/subject/jbxvbttx.html