可以将 UIGestureIdentiizer 附加到多个视图吗?

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)];
[self.view1 addGestureRecognizer:tapGesture];
[self.view2 addGestureRecognizer:tapGesture];
[tapGesture release];

在上面的代码中,只能识别 view2上的敲击。如果我注释掉第三行,那么点击 view1就会被识别出来。如果我是正确的,你只能使用一次手势识别器,我不知道这是一个错误或它只是需要一些更多的文档。

86828 次浏览

UIGestureRecognizer将用于单个视图。我同意文件是参差不齐的。UIGestureRecognizer有一个单独的view属性泄露了它:

视图

手势识别器附加到的视图。(只读)

@property(非原子,只读)UIView *view

你附加(或添加)一个手势识别器到一个UIView对象 使用addGestureRecognizer: 方法。< / p >

我使用下面的方法来解决这个问题。

for (UIButton *aButton in myButtons) {


UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
longPress.minimumPressDuration=1.0;
[aButton addGestureRecognizer:longPress];
[longPress release];


}

然后在我的handleLongPress方法中,我只是设置一个UIButton等于手势识别器的视图,并根据该按钮分支我所做的事情

- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
UIButton *whichButton=(UIButton *)[gesture view];
selectedButton=(UIButton *)[gesture view];
....
}

好吧,如果有人不想代码添加手势视图的多个按钮像kwalker已经回答上面,并想通过接口生成器这样做,这可能会帮助你。

1)你可以从对象库中添加长按手势识别器,就像你添加其他对象,如UIButtons和UILabels。

enter image description here 最初我只用了一个

2)将引用出口设置为UIButton,并与文件的所有者一起发送操作。

enter image description here

注意:如果你有多个UIButton或任何其他对象,你将需要单独的手势识别器为他们每一个。详情请参考我的这个问题。长按手势识别器上的UIButton标签错误

你可以用这段代码我的视图,也就是xib中的imageviews。

- (void)viewDidLoad
{
firstIV.tag = 501;
secondIV.tag = 502;
thirdIV.tag = 503;
forthIV.tag = 504;


[self addTapGesturetoImageView: firstIV];
[self addTapGesturetoImageView: secondIV];
[self addTapGesturetoImageView: thirdIV];
[self addTapGesturetoImageView: forthIV];
}


-(void)addTapGesturetoImageView:(UIImageView*)iv
{
iv.userInteractionEnabled = YES;
UITapGestureRecognizer * textfielBGIVTapGasture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(textfielBGIVTapped:)];
textfielBGIVTapGasture.numberOfTapsRequired = 1;
[iv addGestureRecognizer:textfielBGIVTapGasture];
}


- (void)textfielBGIVTapped:(UITapGestureRecognizer *)recognizer {
int tag = recognizer.view.tag-500;
switch (tag) {
case 1:
{
//firstIV tapped;
break;
}
case 2:
{
//secondIV tapped;
break;
}
case 3:
{
//thirdIV tapped;
break;
}
case 4:
{
//forthIV tapped;
break;
}
default: {
break;
}
}
}

不,你不应该将手势识别器附加到多个视图。

苹果文档中有这样明确的信息:

手势识别器附加到视图

每个手势识别器都与一个视图相关联。相比之下,a 视图可以有多个手势识别器,因为一个视图 可能会对许多不同的手势做出反应。对于一个手势识别器 标识在特定视图中出现的触摸,必须附加

苹果开发者库

正如其他人提到的那样,它们在某些情况下可能会起作用,但这显然违背了文档,并且可能会在未来的任何iOS版本中更改。

你所能做的就是向你想要监视的视图添加单独的手势识别器,它们可以共享一个共同的动作。

通过'<UIScrollViewDelegate>'重写类

在.m类中使用这个方法:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}

此方法将帮助您在一个视图上启用多个滑动。

重写(重建)你的gesturerecogize每次你添加一个手势识别器指向相同的功能。 在下面的情况下,它是有效的。我使用IBOutletCollection

斯威夫特2:

@IBOutlet var topicView: [UIView]!


override func viewDidLoad() {
for view in self.topicView as [UIView] {
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "viewClicked:"))
}
}


func viewClicked(recognizer: UITapGestureRecognizer) {
print("tap")
}

我们可以做一些像这样的事情,这很简单

1)在控制器中创建如下函数(此函数将返回GestureRecognizer)

-(UITapGestureRecognizer*)setRecognizer{
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openProfile)];
[gestureRecognizer setNumberOfTapsRequired:1];
return gestureRecognizer;
}

2)现在在多个视图中设置这个识别器

[self.view1 addGestureRecognizer:[self setRecognizer]];
[self.view2 addGestureRecognizer:[self setRecognizer]];

对于Swift 3,如果有人需要这个: 基于Bhavik Rathod的回答。< / p >

 func setGestureRecognizer() -> UIPanGestureRecognizer {


var panRecognizer = UIPanGestureRecognizer()


panRecognizer = UIPanGestureRecognizer (target: self, action: #selector(pan(panGesture:)))
panRecognizer.minimumNumberOfTouches = 1
panRecognizer.maximumNumberOfTouches = 1
return panRecognizer
}


///set the recognize in multiple views
view1.addGestureRecognizer(setGestureRecognizer())
view2.addGestureRecognizer(setGestureRecognizer())

如果你有固定的视角,我建议你这样做

[self.view1 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];
[self.view2 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];

这样可以减少多个不同的无用变量

你可以在视图上创建一个通用扩展来轻松添加手势识别器。 这只是一个例子,但它看起来像这样

extension UIView {


func setGestureRecognizer<Gesture: UIGestureRecognizer>(of type: Gesture.Type, target: Any, actionSelector: Selector, swipeDirection: UISwipeGestureRecognizer.Direction? = nil, numOfTaps: Int = 1) {
let getRecognizer = type.init(target: target, action: actionSelector)


switch getRecognizer {
case let swipeGesture as UISwipeGestureRecognizer:
guard let direction = swipeDirection else { return }
swipeGesture.direction = direction
self.addGestureRecognizer(swipeGesture)
case let tapGesture as UITapGestureRecognizer:
tapGesture.numberOfTapsRequired = numOfTaps
self.addGestureRecognizer(tapGesture)
default:
self.addGestureRecognizer(getRecognizer)
}
}


}

要在视图上添加一个2点识别器,你只需调用:

let actionSelector = #selector(actionToExecute)
view.setGestureRecognizer(of: UITapGestureRecognizer.self, target: self, actionSelector: actionSelector, numOfTaps: 2)

您还可以轻松地添加一个滑动识别器

view.setGestureRecognizer(of: UISwipeGestureRecognizer.self, target: self, actionSelector: actionSelector, swipeDirection: .down)

等等。 只要记住,目标必须链接到选择器

我知道这是一个旧帖子,但我认为类似的东西,希望它对其他人有用。我简单地将我的imageViews存储在一个数组中,并将其分配给一个函数中的相同手势识别器来设置每个图像视图。

在我的viewDidLoad():

imageViewList = [imageView, imageView2, imageView3]
setupImageViews(imageViews: imageViewList)

设置图像视图的函数:

func setupImageViews(imageViews: [UIImageView]) {
    

for imageView in imageViews {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
        

//set up image to be displayed with the right aspect
imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleBottomMargin, .flexibleRightMargin, .flexibleLeftMargin, .flexibleTopMargin]
imageView.contentMode = .scaleAspectFit // OR .scaleAspectFill
imageView.clipsToBounds = true
}
}

在动作选择器imagetapping()中,您可以为所选中的任何图像视图设置相应的代码。

@objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
switch tapGestureRecognizer.view {
case imageView:
print("tapped Image View 1") //add your actions here
case imageView2:
print("tapped Image View 2") //add your actions here
case imageView3:
print("tapped Image View 3") //add your actions here
default:
print("Tap not detected")
}
_ = tapGestureRecognizer.view as! UIImageView
//additional code...
}