2017-05-30 4 views
0

ページングを有効にした私のscrollViewのすべてのページの背景にビデオがあります。私は、ビデオを見ることができる領域がタップされているときにビデオを再生/一時停止させたい(名前と画像のラベルを含むUIViewと下部のタブバーの間の左の画像を参照)(ビデオサブビューの上に別のサブビューが各ページ:トップ情報)。 (すべてのページには、これらの特性を持たなければならないので、forループ)それはループのために、次のされて達成するために使用されるコード:新しいUIViewでUITapGestureをブロックしています

//add subviews (pages) 
for (pageIndex, page) in pagesViews.enumerated(){ 

    //...create pages with views 

    //add Subview with videoplayer frame to individual "pages" 
    let videoPlayerFrame = CGRect(x: 0, y: 0, width: pageSize.width, height: pageSize.height) 
    let videoPlayerView = PlayerView(frame: videoPlayerFrame) 
    page.addSubview(videoPlayerView) 

    //add Subview with top info frame to individual "pages" 
    let postInfoFrame = CGRect(x: 0, y: 0, width: pageSize.width, height: 80) 
    let infoView = PostView(frame: postInfoFrame) 
    page.addSubview(infoView) 

    //WORKS FINE UNTIL HERE 


    //NEW SUBVIEW 
    //add Subview with bottom info frame to individual "pages" 
    let postPropertiesFrame = CGRect(x: 0, y: (pageSize.height - 200)/2, width: pageSize.width, height: 200) 
    let propertiesView = PostPropsView(frame: postPropertiesFrame) 
    page.addSubview(propertiesView) 

} 

新しいサブビューが追加されていない場合、それは次のようになります。WORKS UNTIL HERE

をしかし

lass PlayerView: UIView { 

    //create spinner view 
    let activityIndicatorView: UIActivityIndicatorView = { 

     //define properties 
     let aiv = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) 
     aiv.translatesAutoresizingMaskIntoConstraints = false 

     //start spinner 
     aiv.startAnimating() 

     return aiv 

    }() 

    //create controls container view containing the spinner 
    let controlsContainerView: UIView = { 

     //set properties of controls container view 
     let controlView = UIView() 
     controlView.backgroundColor = UIColor(white: 0, alpha: 1) 

     return controlView 

    }() 

    override init(frame: CGRect){ 

     super.init(frame: frame) 

     //function below this override init 
     setupPlayerView() 

     //add subview with controls (e.g. spinner) 
     controlsContainerView.frame = frame 
     addSubview(controlsContainerView) 

     //add to subview and center spinner in subview 
     controlsContainerView.addSubview(activityIndicatorView) 
     activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true 
     activityIndicatorView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 

     //enable interaction 
     controlsContainerView.isUserInteractionEnabled = true 

     //function below this override init 
     defInteractions() 

     //backgorund color of player 
     backgroundColor = .black 

    } 

    //define interactions (doupletap and singletap) 
    func defInteractions(){ 

     //singletap 
     let singleTap = UITapGestureRecognizer(target: self, action: #selector(singleTapDetected(_:))) 
     singleTap.numberOfTapsRequired = 1 

     //controlsContainerView 
     controlsContainerView.addGestureRecognizer(singleTap) 
    } 

    //define type 
    var player: AVPlayer? 

    //set playing to false 
    var isPlaying: Bool = false 

    //PLAY?PAUSE VIDEO WHEN video tapped 
    func singleTapDetected(_ sender: UITapGestureRecognizer) { 

     //play or pause 
     if(!isPlaying){ 

      //play 
      player?.play() 
      isPlaying = true 

     } 
     else{ 

      //pause 
      player?.pause() 
      isPlaying = false 

     } 

    } 

    //setup video in background 
    func setupPlayerView() { 

     //insert url 
     let urlString = "https://blurtime.com/images/testvideo.mov" 

     //check URL if can be converted to NSURL 
     if let videoURL = NSURL(string: urlString){ 

      //player's video 
      if self.player == nil { 
       player = AVPlayer(url: videoURL as URL) 
      } 

      //add sub-layer 
      let playerLayer = AVPlayerLayer(player: player) 
      self.layer.addSublayer(playerLayer) 
      playerLayer.frame = self.frame 

      //when are frames actually rendered (when is video loaded) 
      player?.addObserver(self, forKeyPath: "currentItem.loadedTimeRanges", options: .new, context: nil) 

      //loop through video 
      NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player?.currentItem, queue: nil, using: { (_) in 
       DispatchQueue.main.async { 
        self.player?.seek(to: kCMTimeZero) 
        self.player?.play() 
       } 
      }) 

     } 

    } 

    //what to do when video is loaded (spinner shall disappear) 
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 

     //when frames are actually being rendered 
     if keyPath == "currentItem.loadedTimeRanges" { 

      activityIndicatorView.stopAnimating() 
      controlsContainerView.backgroundColor = .clear 

     } 

    } 

    //reuired as suggested by XCode 
    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

} 

私が追加した場合、:私はビデオ領域((例えばスピナーは重要ではありません)最初の概要を取得するためのコメントを読んで)をタップすると最初のサブビューの基本となるPlayerViewクラスは、ビデオの再生/一時停止しますのサブビュークラスそれ以上完全には動作しません。黄色の領域がタップされている場合は、それでも赤い領域では機能しませんが、右の図のように機能します。赤色の領域がタップされていると、なぜそれが下の黄色の領域で機能するのですか?誰でもこの問題に解決策(および説明)を提供できますか?

答えて

2

新しいビューは、タップジェスチャ認識機能を持つビューの上にあり、それらのタッチを傍受しており、ハンドラがありません。

おそらく、PostPropsViewとビデオプレーヤーの両方を含む新しいUIViewを作成し、ビデオの代わりにその上にタップジェスチャ認識ツールを置くのでしょうか?私はあなたが直接ビデオプレーヤーにUIViewを追加することができるとは思わない。

2

はジェイクT.は、あなたが何をすべきかそれと

let singleTap = UITapGestureRecognizer(target: self, action: #selector(singleTapDetected(_:))) 
singleTap.numberOfTapsRequired = 1 
singleTap.cancelsTouchesInView = false 

、あなたが望む結果を得るでしょう、あなたのTapGesture宣言でこれを追加することですタップジェスチャー認識はタップを吸収している、言ったように

+0

私は 'singleTap.cancelsTouchesInView = false'を追加しましたが、赤い領域をタップしてもまだ動作しません...私はJake Tsの方法と一緒に行かなければなりません – Moritz

関連する問題