如何找出用户使用UIPanGestureRecognizer进行平移的方向?

时间:2016-10-31 21:42:31

标签: ios swift uigesturerecognizer uipangesturerecognizer

所以我在我的项目中使用UIPanGestureRecognizer,我将其添加到视图中。 我想知道用户何时向上,向下,向左或向右。我正在使用左右功能来浏览视频。上下手势仍有待确定。我使用了以下代码,但我似乎无法弄明白。谢谢您的帮助!

@IBAction func panVideo(_ recognizer: UIPanGestureRecognizer) {

    let vel = recognizer.velocity(in: self.videoView)
    if vel.x > 0 {
        // user dragged towards the right
        print("right")
    }
    else {
        // user dragged towards the left
        print("left")
    }
}

编辑:使用滑块

if let duration = avPlayer?.currentItem?.duration {
        let totalSeconds = CMTimeGetSeconds(duration)

        let value = Float64(scrubberSlider.value) * totalSeconds

        let seekTime = CMTime(value: Int64(value), timescale: 1)

        avPlayer?.seek(to: seekTime, completionHandler: { (completedSeek) in
            //perhaps do something later here
        })
    }

3 个答案:

答案 0 :(得分:1)

Joe的答案很接近,但它不会考虑直接垂直或水平平移。 (我会评论他的答案,但格式化不会。)试试这个:

let vel = recognizer.velocity(in: self.videoView)
if vel.x > 0 {
    // user dragged towards the right
    print("right")
}
else if vel.x < 0 {
    // user dragged towards the left
    print("left")
}

if vel.y > 0 {
    // user dragged towards the down
    print("down")
}
else vel.y < 0 {
    // user dragged towards the up
    print("up")
}

}

本质上,你得到手势的CGPoint(x,y)并确定运动的速度。你有另一种选择 - 从起点和终点:

var startingPoint = CGPoint.zero
@IBAction func panVideo(_ recognizer: UIPanGestureRecognizer) {

    if recognizer.state == .began {
        startingPoint = recognizer.location(in: self.videoView)
    }
    if recognizer.state == .ended {
        let endingPoint = recognizer.location(in: self.videoView)
        [ do the same comparing as above]
    }
}

第二个选项的优点是你没有在平底锅期间进行不必要的计算。缺点是某些场景(如动画视图移动)不利于它。

编辑:我在阅读你的评论后添加了更多的措辞。听起来你可能还没有完全理解泛手势是什么。

  • 与大多数(全部?)手势一样,它有一个开头,一个中间和结束。
  • 这是一个二维拖动,包含x和y两个组件。
  • 实际上有七种可能的状态,但它们中的四种(取消,失败,可能,被识别)不会发生平移手势,而是会触发三种状态(开始,更改,结束)。

我抛出了一个例子 - 先用平移手势移动视图。现在我将尝试第二个 - 例如,在图像中描绘自由女神像的轮廓。

在这里,您需要所有三种状态,以便知道何时进行跟踪,何时路径发生变化以及何时结束。并将此限制为更改状态,我认为您可以看到两者 X Y坐标的变化。

所以是的,“左,上,左,上,左”的记录很有可能。我认为如果你在整个屏幕上描绘一条完全垂直的线,你可能会期望所有“向上”或“向下”你的日志中的值,但任何人类平移这种完美的可能性是不太可能的,所以肯定的是,可能会发生一些“左”或“权利”。

  • 我对Joe的代码的调整是为了消除那些完美的时刻。如果vel.x == 0你会有“左”,而bel.y == 0你会有“向下”。

  • 同样,如果您只是想知道平底锅的“结果”是什么,请使用.began和.ended并忽略.changed - 不要使用Recognizer.velocity而应使用Recognizer.state。

  • 我们俩给你的“if”陈述都是真正的框架。如果你理解状态和事物的二维性质,你需要使用.changed,然后调整那些“if”语句 - 也许比较X到Y的速度并取更大的,或消除X或Y变化低于阈值的变化。

答案 1 :(得分:0)

在Swift 3中测试此代码

更新后的答案:下面的代码会在触摸开始时为您提供视图的起始和结束位置。

 if recognizer.state == .began { 
 let vel = recognizer.velocity(in: view) // view is your UIView
  if vel.x > 0 {
  print("right")
  } else {
  print("left")
  }
 }

 if recognizer.state == .ended {
 let vel = recognizer.velocity(in: view)
 if vel.y > 0 {
 print("down")
 } else {
 print("up")
 }
 }

注意:您的答案实际隐藏在您的代码中?

 @IBAction func panVideo(_ recognizer: UIPanGestureRecognizer) {

 let vel = recognizer.velocity(in: self.videoView)
 if vel.x > 0 {
    // user dragged towards the right
    print("right")
 }
 else {
    // user dragged towards the left
    print("left")
 }

 if vel.y > 0 {
    // user dragged towards the down
    print("down")
 }
  else {
    // user dragged towards the up
    print("up")
 }
}

希望这会有所帮助...

答案 2 :(得分:0)

好的,现在我得到了正确的心理图片。你想要擦洗控制。这是一个非常不同的东西,我建议使用UISlider而不是使用手势 - 强烈推荐它。对于初学者来说,他们已经内置了pan手势!这就是我认为像YouTube,QuickTime等应用程序。

  • (1)让我们举一个长度为1:53:22的视频,或者(1 * 60 * 60)+(53 * 60)+22 = 6802秒长。

  • (2)添加&#34;洗涤器&#34;子视图到主屏幕。你可能想要一个UISlider,两个UILabel(滑块两侧各一个),还有你想要的任何其他东西。

  • (3)UISLider的minimumValue为0秒,maximumValue为6802秒。当然,您希望在每次更改来源时计算最大值。

  • (4)您要为自己的应用程序回答的一个问题是,是否要使用iTunes的路径(此浏览器视图始终可见)或YouTube(当用户过度可见时)或鼠标光标悬停在某个区域上)。对于前者,您只需将此磨砂视图定位在屏幕上的某个位置即可。对于后者,您可能希望使用平移手势 - 但仅用于可见性。坚持这一想法。

  • (5a)你在UISlider上需要两件,或许还有三件东西。首先是自动值更新。同样,它将取决于整个磨砂视图的可见性。如果它始终可见,您希望每秒更新左手UILabel和UISLider值。对于一个消失的人,你可能只能在它可见时每秒更新一次。

  • (5b)您需要对UISlider进行的第二件事是用户对其进行的跟踪更改(&#34;擦洗&#34;),同时它是可见的。您正在寻找的事件是UIControl.valueChanged()。它会在用户使用滑块的任何时候触发,为您提供新的秒值以及#34; scrub&#34;视频到。

  • (5c)您可能想要使用UISlider进行的第三件事是通过几种方式对其进行自定义 - 更改拇指图像和滑块本身。我的应用更改了拇指图像。这些只能在代码中完成,没有IB属性可用。

回到#4。 以上所有内容都不需要平移手势,除非您希望仅在需要时才显示围巾视图。

如果您对我上面描述的内容有所了解,那么您只想知道一个平移手势是否已经发生。不关心方向。您可能希望对屏幕区域有一些问题 - 当用户平移不会出现磨砂视图的区域时,是否希望显示此磨砂视图?

使用平移手势连接CALayer(或整个视频视图)。 然后编写UIGestureRecognizer.began状态的代码。通过将磨砂视图的状态从0更改为1,或者&#34;滑动&#34;使磨砂视图可见。通过改变它的起源或高度来看它。添加一个UIView.animate(withDuration :)以获得良好的效果。

现在,剩下的就是将磨砂视图设置回自然状态。你需要编写与你所做的任何事情相反的代码,然后将它附加到一个计时器上,这个计时器设置为你希望它显示的几秒钟。

<强> TL; DR;

我的应用程序使用4个UISliders来改变使用CoreImage的照片效果的各种事物(高度,宽度,饱和度,格栅厚度)。性能非常紧凑,大约5/100秒可以获取所有4个滑块的新值并更新图像。

这些滑块今天始终可见,但我的下一次更新(大约2周后)将配备一个&#34;滑动控制板&#34; - 想一下带有滑块和其他控件的键盘。 (自定义键盘的alpha值存在限制,迫使我自己编写,但这是一个单独的讨论。)

所以我知道&#34;滑动磨砂视图&#34;是可能的。我不知道的是,如果将alpha值设置为零视图,它是否会检测到平移手势?我不知道,因此可能需要CALayer。