読者です 読者をやめる 読者になる 読者になる

hiragram no blog

iOSとか

UIViewのアニメーション中にタップイベントが発生しなくてハマった自戒

起きたこと

  • UITableViewをスクロールしてると、たまに指が滑る(縦にスワイプしてもtableViewが追従してこない)ような違和感があった
  • 最近、UITableViewのセル内の画像をUIViewのtransitionWithViewを使ってフェードインさせるように改修してた
  • フェードインが怪しいと思ってdurationを10秒とかにして試してみたら案の定アニメーション中に画像を触ってもなにも反応しなかった
  • 直すぞ
  • 直らん

やったこと

UIResponder周りかな…?

もともとタッチの判定をUIResponderのtouchesBeganをオーバーライドしてやってたのでその辺から疑ってかかった。

確かにフェードインのアニメーション中に画像をタップしても、touchesBeganが呼ばれてない。

じゃーアニメーションしてる間のタップイベントはどこに通知されてるんだと思い子やら親やらいろいろ見たけどどこにも行ってないっぽい。

「こいつがイベントを受け取ってないなら、どっかで受け取ってるビューがいるはず」と思い込んでしまい、そいつを探しはじめてハマってしまった。

transitionWithViewからanimateWithDurationに変えてみる

結果同じ。

UIResponderじゃなくてUITapGestureRecognizer使ってみる

てっきりUIResponderが悪いと思っていたので、recognizer作ってイベント貼ってやれば通知来るだろうと思ったけど来なかった。これ結構がっくりきた。

UIViewAnimationOptionsのドキュメントもっかい見た

UIViewAnimationOptions ここ

struct UIViewAnimationOptions : OptionSetType {
    init(rawValue rawValue: UInt)
    static var LayoutSubviews: UIViewAnimationOptions { get }
    static var AllowUserInteraction: UIViewAnimationOptions { get } // <- あっ
    static var BeginFromCurrentState: UIViewAnimationOptions { get }
    static var Repeat: UIViewAnimationOptions { get }
    static var Autoreverse: UIViewAnimationOptions { get }
    static var OverrideInheritedDuration: UIViewAnimationOptions { get }
    static var OverrideInheritedCurve: UIViewAnimationOptions { get }
    static var AllowAnimatedContent: UIViewAnimationOptions { get }
    static var ShowHideTransitionViews: UIViewAnimationOptions { get }
    static var OverrideInheritedOptions: UIViewAnimationOptions { get }
    static var CurveEaseInOut: UIViewAnimationOptions { get }
    static var CurveEaseIn: UIViewAnimationOptions { get }
    static var CurveEaseOut: UIViewAnimationOptions { get }
    static var CurveLinear: UIViewAnimationOptions { get }
    static var TransitionNone: UIViewAnimationOptions { get }
    static var TransitionFlipFromLeft: UIViewAnimationOptions { get }
    static var TransitionFlipFromRight: UIViewAnimationOptions { get }
    static var TransitionCurlUp: UIViewAnimationOptions { get }
    static var TransitionCurlDown: UIViewAnimationOptions { get }
    static var TransitionCrossDissolve: UIViewAnimationOptions { get }
    static var TransitionFlipFromTop: UIViewAnimationOptions { get }
    static var TransitionFlipFromBottom: UIViewAnimationOptions { get }
}

あっ

UIView.transitionWithView(self, duration: 1.0, 
  options: [.TransitionCrossDissolve, .AllowUserInteraction], 
  animations: { () -> Void in
    self.alpha = 1
  },
  completion: nil
)

これでいけた(.TransitionCrossDissolveは元から渡してた)

反省

ドキュメントを読みましょう

メソッドにoptionとか渡してたらまずそこを見ましょう

反省します。