UIScrollView setZoomScale sets the applied rotation back to Zero

烈酒焚心 提交于 2019-12-12 10:46:44

问题


I've been working on a maps replacement for quite a while now. The whole thing works with a UIScrollView backed by a CATiledLayer.

To rotate my map, i rotate the layer itself. (Using CATransform3DMakeRotation) Works pretty well so far =)

But if I ever call setZoomScale method the CATransform3D that is going to be submitted to my layer is resetting the rotation to 0.

My question is, is there any way to set the zoomscale of my scrollView without loosing the applied rotation?

The same problem exists for the pinch gestures.

//Additional Infos

To rotate around the current Position, i have to edit the anchor point. Maybe this is a problem for the scaling, too.

- (void)correctLayerPosition {
    CGPoint position    = rootView.layer.position;
    CGPoint anchorPoint = rootView.layer.anchorPoint;
    CGRect  bounds      = rootView.bounds;
    // 0.5, 0.5 is the default anchorPoint; calculate the difference
    // and multiply by the bounds of the view
    position.x              = (0.5 * bounds.size.width) + (anchorPoint.x - 0.5) *    bounds.size.width;
    position.y              = (0.5 * bounds.size.height) + (anchorPoint.y - 0.5) * bounds.size.height;
    rootView.layer.position = position;
}

- (void)onFinishedUpdateLocation:(CLLocation *)newLocation {
    if (stayOnCurrentLocation) {
        [self scrollToCurrentPosition];
    }
    if (rotationEnabled) {
        CGPoint anchorPoint        = [currentConfig layerPointForLocation:newLocation];
        anchorPoint.x              = anchorPoint.x / rootView.bounds.size.width;
        anchorPoint.y              = anchorPoint.y / rootView.bounds.size.height;
        rootView.layer.anchorPoint = anchorPoint;
        [self correctLayerPosition];
    }
}

回答1:


You can implement scrollViewDidZoom: delegate method and concatenate the two transforms to achieve desired effect:

- (void) scrollViewDidZoom:(UIScrollView *) scrollView
{
    CATransform3D scale = contentView.layer.transform;
    CATransform3D rotation = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);

    contentView.layer.transform = CATransform3DConcat(rotation, scale);
}

EDIT

I've got simpler idea! How about adding another view to the hierarchy with the rotation transform attached? Here's the proposed hierarchy:

  • ScrollView
    • ContentView - the one returned by viewForZoomingInScrollView:
      • RotationView - the one with rotation transform
        • MapView - the one with all the tiles

I don't think that performance should be any concern here and it's worth trying.



来源:https://stackoverflow.com/questions/12006171/uiscrollview-setzoomscale-sets-the-applied-rotation-back-to-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!