使用Transform旋转时调整UIView的大小 [英] Resize UIView While It Is Rotated with Transform

查看:121
本文介绍了使用Transform旋转时调整UIView的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我的 UIView 使用transform属性( CGAffineTransformMakeRotation )旋转时,我需要拖动其中一个角,说右下角,调整大小。在此过程中,当用户拖动角落时,视图的角落必须跟随用户的手指,并通过增加2个边(右下角拖动的右下角)来调整框的大小。

When my UIView is rotated with transform property (CGAffineTransformMakeRotation), I need to drag one of its corners, say bottom right, to resize it. During this process when user drags the corner, the view's corner must follow user's finger and resize the box by increasing 2 of the sides (right and bottom size for bottom right corner dragging).

当不转换框时,可以使用框架和触摸位置来调整 UIView 的大小并不困难。例如,我会记住初始帧和触摸 UIPanGestureRecognizer 处理程序附加到 StateBegan <上的这个可调整大小的视图/ em>,和 StateChanged 我会计算触摸点X,Y与初始触摸的差异,并将这些值添加到初始帧宽和高度。

It is not so difficult to resize UIView when you can use frame and touch locations when box is not transformed. For example, I would remember initial frame and touch in UIPanGestureRecognizer handler attached to this resizable view on StateBegan, and on StateChanged I would calculate the touch point X, Y difference from initial touch and add those values to initial frame width and height.

但是,当应用变换时,对于旋转的 UIView ,帧是可靠的。因此,我只能依赖界限中心。我创建了这个代码但它几乎可以工作:我只能按比例放大所有4个方向的视图,而不是一个。

However, frame is be reliable for rotated UIView when transform is applied. Thus I can only rely on bounds and center. I created this code but it almost works: I can only enlarge the view proportionally in all 4 directions, not one.

- (void)handleResizeGesture:(UIPanGestureRecognizer *)recognizer {
    CGPoint touchLocation = [recognizer locationInView:self.superview];
    CGPoint center = self.center;

    switch (recognizer.state) {
        case UIGestureRecognizerStateBegan: {
            deltaAngle = atan2f(touchLocation.y - center.y, touchLocation.x - center.x) - CGAffineTransformGetAngle(self.transform);
            initialBounds = self.bounds;
            initialDistance = CGPointGetDistance(center, touchLocation);
            initialLocation = touchLocation;
            if ([self.delegate respondsToSelector:@selector(stickerViewDidBeginRotating:)]) {
                [self.delegate stickerViewDidBeginRotating:self];
            }
            break;
        }

        case UIGestureRecognizerStateChanged: {

            CGFloat scale = CGPointGetDistance(center, touchLocation)/initialDistance;
            CGFloat minimumScale = self.minimumSize/MIN(initialBounds.size.width, initialBounds.size.height);
            scale = MAX(scale, minimumScale);
            CGRect scaledBounds = CGRectScale(initialBounds, scale, scale);
            self.bounds = scaledBounds;

            [self setNeedsDisplay];

            if ([self.delegate respondsToSelector:@selector(stickerViewDidChangeRotating:)]) {
                [self.delegate stickerViewDidChangeRotating:self];
            }
            break;
        }

        case UIGestureRecognizerStateEnded:
            if ([self.delegate respondsToSelector:@selector(stickerViewDidEndRotating:)]) {
                [self.delegate stickerViewDidEndRotating:self];
            }
            break;

        default:
            break;
    }
}

下图显示了已知值的旋转视图(A ,B,x,y,N,M,NM距离):

Image below shows the rotated view with known values (A, B, x, y, N, M, N-M distance):

推荐答案

不错的问题。我刚刚创建了使用类似东西的类。在我班上你可以改变UIViewA的比例,它会改变UIViewB的比例,同时保持相同的比例。

Nice question. I've just created class that uses something similar. In my class you can change the scale of UIViewA and it will change the scale of UIViewB while keeping the same ratio.

检查左上角的小白方:

该课程可在此处找到: https://github.com/sSegev/SSUIViewMiniMe

The class can be found here: https://github.com/sSegev/SSUIViewMiniMe

你问的是有点不同。我正在改变方块的总大小,而你想根据用户拖动它的距离只改变相对于其中一个角的大小。

What you are asking is a bit different. I'm changing the total size of the square while you want to change only the size that is relative to one of the corners based on how far the user dragged it.

因为在动画时你不能点击一个按钮(好吧,你可以,但动画只是眼睛糖果,视图已经处于最终状态)我使用CABasicAnimation使它更容易。

Because you can't tap on a button while it's animating (well, you can but the animation is just eye candy and the view is already in it's final state) I used CABasicAnimation which made it easier.

- (void)viewDidAppear:(BOOL)animated
{
        [super viewDidAppear:animated];
        //Rotate the UIView            
    if ([_myRedView.layer animationForKey:@"SpinAnimation"] == nil)
        {
            CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
            animation.fromValue = [NSNumber numberWithFloat:0.0f];
            animation.toValue = [NSNumber numberWithFloat: 2*M_PI];
            animation.duration = 50.0f;
            animation.repeatCount = INFINITY;
            [self.myRedView.layer addAnimation:animation forKey:@"SpinAnimation"];
        }
}

 // That's the main chunk of code:

- (void)dragBegan:(UIControl *)c withEvent:ev
{
    UITouch *touch = [[ev allTouches] anyObject];
    CGPoint touchPoint = [touch locationInView:_myRedView];
    NSLog(@"Touch x : %f y : %f", touchPoint.x, touchPoint.y);
    if(_myRedView.width/2<touchPoint.x && _myRedView.height/2<touchPoint.y) //Checks for right bottom corner
        {
            _myRedView.width =touchPoint.x;
            _myRedView.height = touchPoint.y;
            dragButton.frame = CGRectMake(0, 0, _myRedView.width, _myRedView.height);
        }
}

我确信需要进行一些调整但是正确现在它看起来像这样:

I'm sure that some tweaking is needed but right now it looks like this:


*

只有6行代码很酷吗?

这篇关于使用Transform旋转时调整UIView的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆