我在scrollView的每个页面的后台都有一个视频,启用了分页。我希望在可以看到视频的区域点击时播放/暂停视频(请参阅左下方的图片,包含带有名称和图像的标签的UIView与底部标签栏之间)(视频子视图中还有另一个子视图)每页:热门信息)。用于实现该代码的代码是以下for循环(for循环,因为每个页面都应具有这些属性):
el.getObject3D('mesh').geometry
//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)
}
课程作为第一个子视图的基础,当我点击视频区域时视频播放/暂停(阅读评论以首先获得概述(例如,微调器不应该重要)):
PlayerView
但是,如果我使用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")
}
}
类添加子视图,它就不再完全正常工作了。如果黄色区域被轻拍,它仍然可以按照需要运行,但不再在红色区域... ...(图片右侧)为什么它在较低的黄色区域工作,如果红色区域是为什么它不再是它挖?任何人都可以为这个问题提供解决方案(和解释)吗?
答案 0 :(得分:2)
新视图位于具有点击手势识别器的视图之上,并且正在拦截这些触摸,并且没有针对它们的处理程序。
也许创建一个新的UIView,其中包含PostPropsView和您的视频播放器,并将点击手势识别器放在其上而不是视频?我不相信你可以直接将UIView添加到视频播放器中。
答案 1 :(得分:2)
正如Jake T.所说,轻敲手势识别器正在吸收水龙头,所以你需要做的就是在你的TapGesture声明上添加它
let singleTap = UITapGestureRecognizer(target: self, action: #selector(singleTapDetected(_:)))
singleTap.numberOfTapsRequired = 1
singleTap.cancelsTouchesInView = false
有了这个,你就会得到你想要的东西