想象一下iOS屏幕,您可以移动手指向上/向下来做某事(想象一下,"比例"),
作为一个单独的功能,您可以移动手指左/右来做某事(想象一下,&#34;更改颜色&#34;或&#34;旋转&#34;)。< / p>
他们是
功能,您只能一次。
所以,如果它&#34;开始为&#34;横向版本,它仍然只是一个横向版本。相反,如果它&#34;开始为&#34;垂直版本,它只是一个垂直版本。
这样做有点棘手,我在下面提出了如何做到这一点......基本模式是:
if (r.state == .Began || panway == .WasZeros )
{
prev = tr
if (tr.x==0 && tr.y==0)
{
panway = .WasZeros
return
}
if (abs(tr.x)>abs(tr.y)) ... set panway
}
这非常有效,而且这里是如何在Swift中完成的。
在故事板中,选择UIPanGestureRecognizer
,将其拖到有问题的视图中。将代理人连接到视图控制器并将出口设置为此呼叫ultraPan:
enum Panway
{
case Vertical
case Horizontal
case WasZeros
}
var panway:Panway = .Vertical
var prev:CGPoint!
@IBAction func ultraPan(r:UIPanGestureRecognizer!)
{
let tr = r.translationInView(r.view)
if (r.state == .Began || panway == .WasZeros )
{
prev = tr
if (tr.x==0 && tr.y==0)
{
panway = .WasZeros
return
}
if (abs(tr.x)>abs(tr.y))
{
panway = .Horizontal
}
else
{
panway = .Vertical
}
}
if (panway == .Horizontal) // your left-right function
{
var h = tr.x - prev.x
let sensitivity:CGFloat = 50.0
h = h / sensitivity
// adjust your left-right function, example
someProperty = someProperty + h
}
if (panway == .Vertical) // bigger/smaller
{
var v = tr.y - prev.y
let sensitivity:CGFloat = 2200.0
v = v / sensitivity
// adjust your up-down function, example
someOtherProperty = someOtherProperty + v
}
prev = tr
}
没关系。
但是,制作UIPanGestureRecognizer 的新子类(或其他东西)肯定会更好,因此有两个新概念......
UIHorizontalPanGestureRecognizer
UIVerticalPanGestureRecognizer
那些基本上是一维的pan ..
我绝对不知道你是否会......委托子类?还是上课? (什么课?),或者某种类型的扩展......的确,我基本上对此完全无能为力:))
目标是在一个代码中,你可以有这样的东西......
@IBAction func horizontalPanDelta( ..? )
{
someProperty = someProperty + delta
}
@IBAction func verticalPanDelta( ..? )
{
otherProperty = otherProperty + delta
}
如何以这种方式继承/扩展UIPanGestureRecognizer
?
答案 0 :(得分:3)
但是制作UIPanGestureRecognizer的新子类(或其他东西)肯定会更好,因此有两个新概念......
UIHorizontalPanGestureRecognizer
UIVerticalPanGestureRecognizer
那些基本上是一维的panners
正确。这正是如何做到的,这是正常的做法。实际上,这正是 的姿势识别器:每个g.r.仅识别其自己的手势,当它识别时,它会使竞争手势识别器退避。这是手势识别器的整个点!否则,我们仍然会回到前期。纯天touchesBegan
等等(哦,恐怖)。
我的在线书籍实际上讨论了你在这里给出的例子:
http://www.apeth.com/iOSBook/ch18.html#_subclassing_gesture_recognizers
这是一个在Swift中实现它的实际可下载示例:
遵守此处使用的策略。我们制作UIPanGestureRecognizer子类。我们覆盖touchesBegan
和touchesMoved
:当识别开始时,我们会在看到下一次触摸沿着错误的轴时失败。 (您应该观看Apple关于此主题的视频;正如他们所说,当您将手势识别器子类化时,您应该“提早失败,经常失败”。)我们还会覆盖translationInView
,以便只能沿着轴直接移动。结果(如果您下载项目本身就可以看到)是一个可以水平或垂直拖动但不以其他方式拖动的视图。
答案 1 :(得分:2)
enum PanDirection {
case Horizontal
case Vertical
}
class OneDimensionalPan: NSObject {
var handler: (CGFloat -> ())?
var direction: PanDirection
@IBOutlet weak var panRecognizer: UIPanGestureRecognizer! {
didSet {
panRecognizer.addTarget(self, action: #selector(panned))
}
}
@IBOutlet weak var panView: UIView!
override init() {
direction = .Horizontal
super.init()
}
@objc private func panned(recognizer: UIPanGestureRecognizer) {
let translation = panRecognizer.translationInView(panView)
let delta: CGFloat
switch direction {
case .Horizontal:
delta = translation.x
break
case .Vertical:
delta = translation.y
break
}
handler?(delta)
}
}
在情节提要中,将UIPanGestureRecognizer
拖到视图控制器上,然后将Object
拖到视图控制器的顶部栏上,设置其类,并链接其IBOutlet
。在那之后你应该好好去。在视图控制器代码中,您可以设置其回调和平移方向。
更新说明&gt;
我想澄清为什么我让这个类成为NSObject
的子类:这个类背后的驱动思想是将任何不必要的代码保留在UIViewController
之外。通过继承NSObject
,我可以将Object
拖到故事板内的视图控制器顶部栏上,并将其类设置为OneDimensionalPan
。从那里,我可以将@IBOutlet
连接到它。我本可以把它变成一个基类,但是它必须以编程方式实例化。这更清洁了。视图控制器中唯一的代码是访问对象本身(通过@IBOutlet
),设置其方向,并设置其回调。