滑动手势时将视图更改为圆圈,iOS、Swift
Change view to a circle on swipe gesture, iOS, Swift
我正在尝试通过滑动手势(向任何方向,快或慢)将视图缩小为圆圈,类似于 WhatsApp videoCall 视图的体验。查看下面的图片,了解我想要实现的目标。
我认为我需要使用滑动手势来实现此目的,我已将滑动手势添加到 videoView,我不确定下一步该怎么做。
在 viewDidLoad 中我有以下内容
videoView.addGestureRecognizer(UISwipeGestureRecognizer(target: self, action: #selector(self.minimiseView) ))
我想我需要使用手势定位?而且我还需要设置随着滑动而增加的角半径。有人可以告诉我如何实现这一目标吗?
func minimiseView(gesture: UISwipeGestureRecognizer){
let location = gesture.location(in: self.view)
}
您基本上想要执行以下步骤:
- 捕捉起始手势位置
- 在滑动过程中,测量与原始滑动的距离
- 使用这个距离来增加相机视野的角半径
- 例如设置
cornerRadius = distanceSwiped
- 一旦圆角半径达到一定量(且视图为圆形),捕获当前手势位置
- 使用此值再次开始跟踪运动并使用它来减小视图的宽度
- 当视图足够小时将其关闭
以下是完成此操作的基本设置:
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)
}
这可能不会完全奏效,因为我还没有测试过,但基本的想法应该足以让你入门。
我正在尝试通过滑动手势(向任何方向,快或慢)将视图缩小为圆圈,类似于 WhatsApp videoCall 视图的体验。查看下面的图片,了解我想要实现的目标。
我认为我需要使用滑动手势来实现此目的,我已将滑动手势添加到 videoView,我不确定下一步该怎么做。
在 viewDidLoad 中我有以下内容
videoView.addGestureRecognizer(UISwipeGestureRecognizer(target: self, action: #selector(self.minimiseView) ))
我想我需要使用手势定位?而且我还需要设置随着滑动而增加的角半径。有人可以告诉我如何实现这一目标吗?
func minimiseView(gesture: UISwipeGestureRecognizer){
let location = gesture.location(in: self.view)
}
您基本上想要执行以下步骤:
- 捕捉起始手势位置
- 在滑动过程中,测量与原始滑动的距离
- 使用这个距离来增加相机视野的角半径
- 例如设置
cornerRadius = distanceSwiped
- 例如设置
- 一旦圆角半径达到一定量(且视图为圆形),捕获当前手势位置
- 使用此值再次开始跟踪运动并使用它来减小视图的宽度
- 当视图足够小时将其关闭
以下是完成此操作的基本设置:
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)
}
这可能不会完全奏效,因为我还没有测试过,但基本的想法应该足以让你入门。