【发布时间】:2016-05-03 15:00:37
【问题描述】:
我正在尝试创建一个名为 MyScrollView 的自定义 UIView/Scrollview,其中包含一些标签 (UILabel),这些标签接收点击手势/事件以响应用户的选择 。
为了使点击事件在 UILabel 上起作用,我确保它们都有 userIteractionEnabled = true 并且我创建了一个如下委托:
protocol MyScrollViewDelegate {
func labelClicked(recognizer: UITapGestureRecognizer)
}
在我创建的ScrollViewController 中使用了自定义 UIView,这个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
}
我对@987654336@ 的观察是touchesBegan() 和touchesEnded() 方法在视图中触发仅 当hitTest 函数存在时。如果没有hitTest,这两个函数都不会被点击调用。
但没有运气让UILabel 回复点击手势。因此,我在这里联系了有关 SO 的专家。感谢您的帮助!
【问题讨论】:
-
在父级的相关触摸方法中,尝试将它们转发给下一个响应者。例如,在父级内的
touchesBegan内,尝试调用self.nextResponder.touchesEnded。 -
您是否为您的标签设置了属性 userInteractionEnabled = true ? UILabel 的默认值是 false,所以如果你想接收手势,你应该改变它。
-
@VladimirK,是的,我确实在所有标签上将
userIteractionEnabled设置为 true。谢谢 -
self.nextResponder()?.touchesEnded()似乎将事件向上发送,而不是向下发送。问题仍然存在。谢谢 -
好的,您是否为添加到标签的手势识别器实现了委托方法:gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:?
标签: ios swift events uiview uitapgesturerecognizer