如何使用 Swift 为多个子视图实现点击手势识别器

How to implement a tap gesture recognizer for multiple subviews with Swift

我有一个带有 3 个静态单元格的 tableView,每个单元格都包含一个带有显示所需文本的标签的子视图,我想要完成的是当用户点击任何一个时,以编程方式将方向从纵向旋转到横向3 个子视图。

我让它为第一个子视图工作。但是,当我尝试将相同的 Tap 手势识别器添加到其他子视图时,它仍然只适用于一个子视图。请指教,我错过了什么?感谢您的任何输入。

纵向:

横向

Table 查看控​​制器代码:

import UIKit

class SampleTableViewController: UITableViewController {

    @IBOutlet weak var newYorkViewWrapper: UIView!
    @IBOutlet weak var sanFranciscoViewWrapper: UIView!
    @IBOutlet weak var chicagoViewWrapper: UIView!

    //Vars
    let tapRec = UITapGestureRecognizer()


    override func viewDidLoad() {
        super.viewDidLoad()

        print("Sample view rendered.")


        //Tap gesture
        tapRec.addTarget(self, action: "tappedView")
        newYorkViewWrapper.addGestureRecognizer(tapRec)
        newYorkViewWrapper.userInteractionEnabled = true
        sanFranciscoViewWrapper.addGestureRecognizer(tapRec)
        sanFranciscoViewWrapper.userInteractionEnabled = true
        chicagoViewWrapper.addGestureRecognizer(tapRec)
        chicagoViewWrapper.userInteractionEnabled = true
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //--------------------------------------------------------
    // MARK: Hide status bar
    //--------------------------------------------------------
    override func prefersStatusBarHidden() -> Bool {
        return true
    }

    func tappedView(){
        let value = UIInterfaceOrientation.LandscapeLeft.rawValue
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }

    //--------------------------------------------------------
    // MARK: View Orientation method
    //--------------------------------------------------------
    override func shouldAutorotate() -> Bool {
        return true
    }


}

when I try to add the same Tap gesture recognizer to the other subviews it still only works for one subview

您很好地回答了自己的问题。你不能这样做:

    newYorkViewWrapper.addGestureRecognizer(tapRec)
    sanFranciscoViewWrapper.addGestureRecognizer(tapRec)
    chicagoViewWrapper.addGestureRecognizer(tapRec)

相反,您必须制作三个不同的 点按手势识别器并向每个 视图添加一个。

正如 Matt 所说,手势识别器仅适用于单一视图。使点击手势识别器与多个视图一起工作的唯一方法是将其附加到父视图,然后编写额外的代码来确定它点击了哪个子视图(如果有)。不过,这通常比它的价值更麻烦,您最好为每个视图创建一个单独的手势识别器。

在某些情况下,我发现将手势识别器附加到超级视图很有用的地方是让用户点击正在动画显示其位置的视图。手势识别器不处理位置动画,所以你必须自己做。

我通过定义 4 个单独的 UITapGestureRecognizer() 变量解决了我自己的问题,如下所示,然后将适当的手势识别器添加到适当的视图。

//Vars
let tapRecForHistoryView = UITapGestureRecognizer()
let tapRecForMissionView = UITapGestureRecognizer()
let tapRecForServiceAreaView = UITapGestureRecognizer()
let tapRecForServiceAreaMapView = UITapGestureRecognizer()


override func viewDidLoad() {
        super.viewDidLoad()
        //Tap gesture
        tapRecForHistoryView.addTarget(self, action: "tappedView")
        tapRecForMissionView.addTarget(self, action: "tappedView")
        tapRecForServiceAreaView.addTarget(self, action: "tappedView")
        tapRecForServiceAreaMapView.addTarget(self, action: "tappedView")
        historyViewWrapper.addGestureRecognizer(tapRecForHistoryView)
        historyViewWrapper.userInteractionEnabled = true
        missionViewWrapper.addGestureRecognizer(tapRecForMissionView)
        missionViewWrapper.userInteractionEnabled = true
        serviceAreaViewWrapper.addGestureRecognizer(tapRecForServiceAreaView)
        serviceAreaViewWrapper.userInteractionEnabled = true
        serviceAreaMapWrapper.addGestureRecognizer(tapRecForServiceAreaMapView)
        serviceAreaMapWrapper.userInteractionEnabled = true
    }

//--------------------------------------------------------
// MARK: Local Methods
//--------------------------------------------------------
func tappedView(){
    let value = UIInterfaceOrientation.LandscapeLeft.rawValue
    UIDevice.currentDevice().setValue(value, forKey: "orientation")
}

我现在可以点击每个单独的视图,方向将以编程方式从纵向旋转到横向。