2016-05-03 2 views
0

いくつかのラベル(UILabel)を含むMyScrollViewというカスタムUIView/Scrollviewを作成しようとしています。これらのラベルは、選択See the below screen shot for the custom UIViewスーパービューに埋め込まれたカスタムUIViewでタップジェスチャー認識機能が受信されない

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のラベルに渡されていません。このため、私はいくつかのGoogle検索を行い、アップルデベロッパーのWebサイトで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と私の観察はhitTest機能があるだけときtouchesBegan()touchesEnded()方法がビューでトリガされていることです。 hitTestがなければ、両方の関数がタップで呼び出されることはありません。

しかし、タックジェスチャーにはUILabelが応答する運がありません。だからここで私は専門家に手を差し伸べています。助けてくれてありがとう!

+1

親の関連するタッチメソッド内で、次のレスポンダに転送してみます。たとえば、親の中の 'touchesBegan'の中で、' self.nextResponder.touchesEnded'を呼び出すことを試みてください。 –

+0

ラベルにuserInteractionEnabled = trueプロパティを設定しましたか?UILabelのデフォルト値はfalseなので、ジェスチャを受け取りたい場合はそれを変更する必要があります。 –

+0

@VladimirK、はい、すべてのラベルで 'userIteractionEnabled'をtrueに設定しました。ありがとう – TonyGW

答えて

3

:のでラベルに.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を設定することです。

アップルデベロッパーのウェブサイトのUIViewのドキュメントをもっと読む必要があります。これが将来私のような人に役立つことを願っています!ありがとうございます!

0

プロパティuserInteractionEnabled = YESを設定する必要があります。

私は UILabelがはるかに闘争した後、タップに反応しなかった理由を見つけたと思う
関連する問題