Swift:为自定义视图添加 Tap

Posted

技术标签:

【中文标题】Swift:为自定义视图添加 Tap【英文标题】:Swift: Adding Taps to Custom Views 【发布时间】:2017-10-14 05:36:49 【问题描述】:

我想将点击添加到子类另一个视图的视图中,但我当前的方法没有被调用,即当我的座位被点击时,座位编号不会被打印,如 handleTap 函数中的编码。我已经从以下post 和this 调整了我的方法。到目前为止我的代码:

//My viewController
class ViewController: UIViewController, UIScrollViewDelegate 
    let scrollView = UIScrollView()
    let cinema: CinemaView = 
        let v = CinemaView()
        return v
    ()

    override func viewDidLoad() 
        super.viewDidLoad()

        let seat1 = SeatView()
        seat1.isVacant = false
        seat1.seatNumber = "2A"

        let seat2 = SeatView()
        seat2.isVacant = true
        seat2.seatNumber = "3B"

        cinema.seats = [seat1, seat2]

        let tap = UITapGestureRecognizer(target: seat1, action: #selector(handleTap))
        seat1.addGestureRecognizer(tap)
        seat1.isUserInteractionEnabled = true

        view.addSubview(scrollView)
        scrollView.addSubview(cinema)

    

    @objc func handleTap(_ seat: SeatView) 
        if let seatNumber = seat.seatNumber 
            print("\(seatNumber) is tapped")
         else 
            print("Seat tapped")
        
    

//My custom cinemaView
class CinemaView: UIView 

    var seats = [SeatView]() 
        didSet 
            for v in self.subviews 
                v.removeFromSuperview()
            
            var seatRect = CGRect(x: 0, y: 0, width: 20, height: 20)
            for seat in seats 
                self.addSubview(seat)
                seat.frame = seatRect
                seatRect.origin.x += seatRect.size.width + 8
             
        
    

    override init(frame: CGRect) 
        super.init(frame: frame)

    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    


//My Custom seatView
class SeatView: UIView 

    var isVacant: Bool = true 
    var seatNumber: String?

    override init(frame: CGRect) 
        super.init(frame: frame)    
    

注意:上面省略了一些样板代码,以使该问题的代码简洁。

我首选的方法是在 VC 中添加这些水龙头,以便我可以将此信息传递到另一个 VC 并推送到 Firebase。任何建议将不胜感激

编辑:添加 UI 截图

【问题讨论】:

尝试使用这个:self 而不是 seat1 在这个声明中 UITapGestureRecognizer(target: seat1, action: #selector(handleTap)) @3stud1ant3 试过了,也没用。 你能显示用户界面的截图吗,座位视图是否正确显示在屏幕上? 我认为问题在于在cinema 视图中添加seat1seat2,因为我认为这不是您正在运行的实际代码,因此很难指出问题所在而且我也认为框架设置不正确 @3stud1ant3 我已经添加了cinemaView的完整代码和UI的截图。到目前为止,座位视图已正确显示。其他代码只是约束。 【参考方案1】:

在 3stud1ant3 的帮助下,我设法找出了哪里出了问题。

在观察视图布局后,即使添加了座位视图,cinemaView 也从未添加到视图中。通过在 viewController 的 viewDidLoad 中为cinemaView 定义更多约束,并在下面的答案帖子中合并 3stud1ant3 的代码,点击功能起作用了。

override func viewDidLoad() 
    super.viewDidLoad()

    view.backgroundColor = .blue

    cinema.seats = [seatView1, seatView2]

    view.addSubview(scrollView)
    scrollView.addSubview(cinema)

    let views = ["scrollView": scrollView, "v": cinema] as [String : Any]
    let screenHeight = view.frame.height

    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[scrollView(\(screenHeight / 2))]", options: NSLayoutFormatOptions(), metrics: nil, views: views))
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[scrollView]|", options: NSLayoutFormatOptions(), metrics: nil, views: views))
    view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-60-[v(50)]", options: NSLayoutFormatOptions(), metrics: nil, views: views))

    //Previously, the below constraints were not added. Once these are added, the tap function works
    cinema.leftAnchor.constraint(equalTo: scrollView.leftAnchor).isActive = true
    cinema.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    cinema.widthAnchor.constraint(equalTo: scrollView.widthAnchor ,constant: 100).isActive = true


【讨论】:

以上是关于Swift:为自定义视图添加 Tap的主要内容,如果未能解决你的问题,请参考以下文章

为自定义包装器视图添加示例视图到 PreviewProvider

为啥我的安卓手机在为自定义滚动视图添加标签栏视图后没有功能

自定义 Facebook 登录视图 Swift

Swift 中的自定义输入视图

将高度设置为自定义视图组

为自定义活动指示器视图使 UIView 半透明