【问题标题】:Change view to a circle on swipe gesture, iOS, Swift在滑动手势、iOS、Swift 上将视图更改为圆形
【发布时间】:2018-02-11 15:40:54
【问题描述】:

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

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

在 viewDidLoad 我有以下

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

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

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

【问题讨论】:

  • 你能解决这个问题吗?如果是,你能在这里分享你的代码吗?

标签: ios swift uiview uigesturerecognizer uianimation


【解决方案1】:

你基本上想要做以下步骤:

  1. 捕获起始手势位置
  2. 在滑动期间,测量与原始滑动的距离
  3. 使用此距离来增加相机视图的角半径
    • 例如设置cornerRadius = distanceSwiped
  4. 一旦圆角半径达到一定量(并且视图是圆形),捕获当前手势位置
  5. 使用此值重新开始跟踪运动并使用它来减小视图的宽度
  6. 当视图足够小时关闭它

以下是您如何完成此操作的基本设置:

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)
}

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

【讨论】:

  • 感谢您的指导,不知道如何计算距离? distance(between: initialGesturePosition, and: currentPosition)
  • @user44776 我在代码末尾为此编写了函数。这只是两个 x, y 坐标的基本距离公式。
  • 我想我需要玩这个才能到达我想去的地方,但它是一个很好的开端..
猜你喜欢
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多