简体   繁体   English

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

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

I have a tableView with 3 Static Cells, each cell contains a subview with labels displaying the desired text, what I want to accomplish is to have the orientation programmatically rotate from Portrait to Landscape when the user taps on any of the 3 subviews. 我有一个带有3个静态单元格的tableView,每个单元格都包含一个带有显示所需文本的标签的子视图,我想要完成的是当用户点击任意3个子视图时,以编程方式将方向从纵向旋转到横向。

I got it working for the first subview. 我让它为第一个子视图工作。 However, when I try to add the same Tap gesture recognizer to the other subviews it still only works for one subview. 但是,当我尝试将相同的Tap手势识别器添加到其他子视图时,它仍然只适用于一个子视图。 Please advise, what am I missing? 请指教,我错过了什么? Thanks for any input. 感谢您的任何意见。

Portrait: 肖像:

在此输入图像描述

Landscape 景观

在此输入图像描述

Table View Controller code: 表视图控制器代码:

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 当我尝试将相同的Tap手势识别器添加到其他子视图时,它仍然只适用于一个子视图

You've answered your own question beautifully. 你已经很好地回答了自己的问题。 You can't do this: 你不能这样做:

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

Instead, you must make three different tap gesture recognizers and add one to each view. 相反,您必须制作三个不同的敲击手势识别器,并为每个视图添加一个

As Matt says, a gesture recognizer only works with a single view. 正如Matt所说,手势识别器仅适用于单一视图。 The only way you can make a tap gesture recognizer work with multiple views would be to attach it to the superview, and then write extra code that figures out which of your subviews (if any) it hit. 使用多个视图可以使轻击手势识别器工作的唯一方法是将其附加到超级视图,然后编写额外的代码来确定它击中了哪些子视图(如果有的话)。 This is usually more trouble than it's worth, though, and you're better off simply creating a separate gesture recognizer for each view. 但这通常比它的价值更麻烦,而且你最好只为每个视图创建一个单独的手势识别器。

On case I've found where it is useful to attach a gesture recognizer to the superview is letting the user tap on a view who's position is being animated. 如果我发现将手势识别器附加到超级视图有用的地方就是让用户点击一个位置正在动画的视图。 Gesture recognizers don't handle position animation, so you have to do that yourself. 手势识别器不处理位置动画,因此您必须自己动手。

I resolved my own issue by defining 4 separate UITapGestureRecognizer() variables as shown below and then adding the appropriate gesture recognizer to the appropriate view. 我通过定义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")
}

I am now able to tap each individual view and the orientation will programmatically rotate from Portrait to Landscape. 我现在可以点击每个单独的视图,并且方向将以编程方式从纵向旋转到横向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM