[英]Tap Gesture Recognizer not received in custom UIView embedded in super view
我正在尝试创建一个名为MyScrollView
的自定义 UIView/Scrollview,其中包含一些标签 (UILabel),这些标签接收点击手势/事件以响应用户的选择 .
为了使点击事件在 UILabels 上工作,我确保它们都具有userIteractionEnabled = true
并且我创建了一个委托,如下所示:
protocol MyScrollViewDelegate {
func labelClicked(recognizer: UITapGestureRecognizer)
}
自定义 UIView 正在我创建的ScrollViewController
中使用,这个ScrollViewController
实现了委托方法:
import UIKit
import Neon
class ScrollViewController: UIViewController, MyScrollViewDelegate {
var curQuestion: IPQuestion?
var type: QuestionViewType?
var lastClickedLabelTag: Int = 0 //
init(type: QuestionViewType, question: IPQuestion) {
super.init(nibName: nil, bundle: nil)
self.curQuestion = question
self.type = type
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func loadView() {
view = MyScrollView(delegate: self, q: curQuestion!)
view.userInteractionEnabled = true
}
}
// implementations for MyScrollViewDelegate
extension ScrollViewController {
func labelTitleArray() -> [String]? {
print("labelTitleArray called in implemented delegate")
return ["Comments", "Answers"]
}
func labelClicked(recognizer: UITapGestureRecognizer) {
print("labelClicked called in implemented delegate")
let controller = parentViewController as? ParentViewController
controller?.labelClicked(recognizer)
lastClickedLabelTag = recognizer.view!.tag
}
}
// MARK: - handle parent's ViewController event
extension QuestionDetailViewController {
func updateActiveLabelsColor(index: Int) {
print("updating active labels color: \(index)")
if let view = view as? MyScrollView {
for label in (view.titleScroll.subviews[0].subviews as? [UILabel])! {
if label.tag == index {
label.transform = CGAffineTransformMakeScale(1.1,1.1)
label.textColor = UIColor.purpleColor()
}
else {
label.transform = CGAffineTransformMakeScale(1,1)
label.textColor = UIColor.blackColor()
}
}
}
}
}
上面的ScrollViewController
被添加,作为父视图控制器的子视图控制器,并定位到父视图的顶部:
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
self.view.backgroundColor = UIColor.whiteColor()
addChildViewController(scrollViewController) // added as a child view controller here
view.addSubview(scrollViewController.view) // here .view is MyScrollView
scrollViewController.view.userInteractionEnabled = true
scrollViewController.view.anchorToEdge(.Top, padding: 0, width: view.frame.size.width, height: 100)
}
该应用程序可以在视图中加载所有内容,但点击手势/事件不会传递到自定义MyScrollView
的标签。 为此,我进行了一些谷歌搜索并阅读了 Apple Developer 网站上的Event Delivery: Responder Chain并进行了命中测试。 下面的hitTest
函数可以在MyScrollView
触发:
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
print("hit test started, point: \(point), event: \(event)")
return self
}
我对hitTest
观察是touchesBegan()
和touchesEnded()
方法只有在hitTest
函数存在时才会在视图中触发。 没有hitTest
,这两个函数都不会被点击调用。
但没有运气让UILabel
响应 Tap Gestures。 所以我在这里与 SO 专家联系。 感谢您的帮助!
我想我找到了UILabel
经过.addGestureRecognizer()
挣扎后没有响应敲击的原因:标签的.addGestureRecognizer()
方法是在我的自定义UIView
组件的init()
方法中运行的,这是错误的,因为视图/标签可能尚未呈现。 相反,我将该代码移至生命周期方法layoutSubviews()
,一切开始运行良好:
var lastLabel: UILabel? = nil
for i in 0..<scrollTitleArr.count {
let label = UILabel()
label.text = scrollTitleArr[i] ?? "nothing"
print("label: \(label.text)")
label.font = UIFont(name: "System", size: 15)
label.textColor = (i == 0) ? MaterialColor.grey.lighten2 : MaterialColor.grey.darken2
label.transform = (i == 0) ? CGAffineTransformMakeScale(1.1, 1.1) : CGAffineTransformMakeScale(0.9, 0.9)
label.sizeToFit()
label.tag = i // for tracking the label by tag number
label.userInteractionEnabled = true
label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.labelClicked(_:))))
titleContainer.addSubview(label)
if lastLabel == nil {
label.anchorInCorner(.TopLeft, xPad: 0, yPad: 0, width: 85, height: 40)
// label.anchorToEdge(.Left, padding: 2, width: 85, height: 40)
} else {
label.align(.ToTheRightMatchingTop, relativeTo: lastLabel!, padding: labelHorizontalGap, width: 85, height: 40)
}
lastLabel = label
}
此外,我不需要实现任何 UIGestureRecognizer 委托方法,也不需要创建容器视图或滚动视图userInteractionEnabled
。 更重要的是,当将自定义 UIView 嵌入到clipsToBounds = true
视图时,我配置了它的大小并设置了clipsToBounds = true
。
我想我应该在 Apple Developer 网站上阅读更多UIView
文档。 希望这会在未来帮助像我这样的人! 谢谢大家!
您必须设置属性userInteractionEnabled = YES
。
出于某种原因,当点击手势识别器不工作时,我的模拟器被冻结或发生了什么。 所以,当我重新启动应用程序时,它又重新开始工作了。 我不知道这是否适用于这里,但这对我来说是解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.