在滑动手势,iOS,Swift上将视图更改为圆圈

时间:2017-09-03 01:13:13

标签: ios swift uiview uigesturerecognizer uianimation

我正试图在滑动手势(任何方向,快或慢)上将视图缩小为圆形,类似于WhatsApp videoCall视图中的体验。请参阅下面的图片,了解我想要实现的目标。

我相信我需要使用滑动手势来实现这一点,我已经为我的videoView添加了一个滑动手势,我不知道下一步该做什么。

在viewDidLoad中我有以下

videoView.addGestureRecognizer(UISwipeGestureRecognizer(target: self, action: #selector(self.minimiseView) ))

我想我需要使用手势定位?而且我还需要设置随着滑动而增加的角半径。有人可以告诉我如何实现这个目标吗?

func minimiseView(gesture: UISwipeGestureRecognizer){
        let location = gesture.location(in: self.view)
    }

enter image description here

1 个答案:

答案 0 :(得分:1)

您基本上想要执行以下步骤:

  1. 捕获起始手势位置
  2. 在滑动过程中,测量与原始滑动的距离
  3. 使用此距离可增加摄像机视图的角半径
    • e.g。设置cornerRadius = distanceSwiped
  4. 一旦角半径达到一定量(并且视图为圆圈),捕捉当前手势位置
  5. 使用此值可以再次开始跟踪动作并使用它来减小视图的宽度
  6. 当视图足够小时将其解雇
  7. 以下是如何完成此操作的基本设置:

    enum VideoDismissState {
        case cornerRadiusChanging, sizeChanging, complete
    }
    
    var initialGesturePosition: CGPoint = .zero
    var maxCornerRadiusGesturePosition: CGPoint = .zero
    var dismissState: VideoDismissState = .complete
    
    func minimiseView(_ gesture: UISwipeGestureRecognizer) {
        let location = gesture.location(in: videoView)
    
        switch gesture.state {
        case .began:
            initialGesturePosition = gesture.location(in: videoView)
            dismissState = .cornerRadiusChanging
        case .changed:
            let currentPosition = gesture.location(in: videoView)
    
            switch dismissState {
            case cornerRadiusChanging:
                let swipeDistance = distance(between: initialGesturePosition, and: currentPosition)
                // play around with this formula to see what feels right
                videoView.layer.cornerRadius = swipeDistance / 2
    
                // at a certain point, switch to changing the size
                if swipeDistance >= videoView.width / 2 {
                    maxCornerRadiusGesturePosition = currentPosition
                    dismissState = .sizeChanging
                }
            case sizeChanging:
                let swipeDistance = distance(between: maxCornerGesturePosition, and: currentPosition)
                // again try different things to see what feels right here
                let scaleFactor = 50 / swipeDistance
    
                videoView.layer.transform = CGAffineTransform(scaledX: scaleFactor, y: scaleFactor
    
                if scaleFactor <= 0.2 {
                    dismissState = .complete
                }
            case complete:
                // reset values
                initialGesturePosition = .zero
                maxCornerRadiusGesturePosition = .zero
    
                // dismiss videoView
                // for example: videoView.isHidden = true OR videoView.removeFromSuperview()
            }
        case .ended:
            // if the gesture ends too soon you may want to animate the view back to full screen
        }
    }
    
    /// Measure distance between two points
    func distance(between first: CGPoint, and second: CGPoint) -> CGFloat {
        return sqrt((first.x - second.x) ^ 2 + (first.y - second.y) ^ 2)
    }
    

    这可能不完全正常,因为我没有测试过,但基本的想法应该足以让你开始。