ページングを有効にした私の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)
}
新しいサブビューが追加されていない場合、それは次のようになります。
をしかし
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
クラスは、ビデオの再生/一時停止しますのサブビュークラスそれ以上完全には動作しません。黄色の領域がタップされている場合は、それでも赤い領域では機能しませんが、右の図のように機能します。赤色の領域がタップされていると、なぜそれが下の黄色の領域で機能するのですか?誰でもこの問題に解決策(および説明)を提供できますか?
私は 'singleTap.cancelsTouchesInView = false'を追加しましたが、赤い領域をタップしてもまだ動作しません...私はJake Tsの方法と一緒に行かなければなりません – Moritz