簡體   English   中英

您可以將 UIGestureRecognizer 附加到多個視圖嗎?

[英]Can you attach a UIGestureRecognizer to multiple views?

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

在上面的代碼中,只能識別對view2點擊。 如果我注釋掉第三行,則可以識別對view1點擊。 如果我是對的並且您只能使用一次手勢識別器,我不確定這是一個錯誤還是只需要更多文檔。

UIGestureRecognizer將與單個視圖一起使用。 我同意文檔是參差不齊的。 UIGestureRecognizer有一個單一的view屬性:

看法

手勢識別器附加到的視圖。 (只讀)

@property(nonatomic, readonly) UIView *view

討論 使用 addGestureRecognizer: 方法將手勢識別器附加(或添加)到 UIView 對象。

我通過使用下面的方法解決了它。

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];
    ....
}

對於 Swift 3,以防萬一有人需要:基於上面的 Bhavik Rathod 回答。

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

我們可以做這樣的事情,很簡單

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]];

不,您不應將手勢識別器附加到多個視圖。

Apple 文檔中有此明確信息:

手勢識別器附加到視圖

每個手勢識別器都與一個視圖相關聯。 相比之下,一個視圖可以有多個手勢識別器,因為一個視圖可能會響應許多不同的手勢。 要讓手勢識別器識別特定視圖中發生的觸摸,您必須將手勢識別器附加到該視圖。

iOS 事件處理指南 - 手勢識別器Apple Developer Library

正如其他人提到的那樣,它們在某些情況下可能會起作用,但這顯然違反了文檔,並且可能會在任何未來的 iOS 版本中更改。

您可以做的是將單獨的手勢識別器添加到您要監視的視圖中,它們可以共享一個通用操作。

好吧,如果有人不想為多個按鈕添加手勢視圖(如kwalker上面已經回答),並且想通過 Interface Builder 來完成,這可能會對您有所幫助。

1) 您可以從對象庫中添加長按手勢識別器,就像添加其他對象(如 UIButtons 和 UILabels)一樣。

在此處輸入圖片說明 最初我最終使用的是我只拿了一個

2) 將引用出口設置為UIButton並使用文件所有者發送操作。

在此處輸入圖片說明

注意:如果您有多個 UIButton 或任何其他對象,您將需要為每個對象使用單獨的手勢識別器。 有關更多詳細信息,請參閱我的這個問題。 在長按手勢識別器上獲取錯誤的 UIButton 標簽

如果你有固定的觀點,我建議你做這樣的事情

[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 tap 識別器,您只需調用:

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)

等等。 請記住,目標必須鏈接到選擇器。

通過“ <UIScrollViewDelegate> ”覆蓋類

並在 .m 類中使用此方法:

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

此方法將幫助您在單個視圖上啟用多次滑動。

每次添加指向相同功能的手勢識別器時,如何重新編寫(重新創建)您的 GestureRecognize。 在下面的情況下它有效。 我正在使用 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")
}

我知道這是一個舊帖子,但我想到了一些類似的東西,希望它對其他人有用。 我只是將我的 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
    }
}

在操作選擇器 imageTapped() 中,您可以為點擊的任何圖像視圖提供相應的代碼。

@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...
}

您可以使用此代碼來完成我的視圖,這些視圖是 xib 中的圖像視圖。

- (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;
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM