如何在UIView中水平居中CALayer?视频播放器偏移问题求助
视频播放器在Cell中居右而非居中,关闭
translatesAutoresizingMaskIntoConstraints后消失的问题 已实现视频播放器功能,但视频显示在Cell右侧而非居中位置,尝试多种方法仍无法解决。关闭playerView.translatesAutoresizingMaskIntoConstraints = false后播放器直接消失。
img_thumb是视频加载前的缩略图容器,当前作为视频黑色背景,因contentView底部有额外元素,故借助其约束进行布局。
布局相关代码
playerView.frame = videoCell.img_thumb.frame // playerView.layer.bounds = videoCell.img_thumb.bounds // playerView.layer.frame = videoCell.img_thumb.frame playerView.layer.position = CGPoint(x: videoCell.img_thumb.bounds.midX, y: videoCell.img_thumb.bounds.midY) videoCell.contentView.addSubview(playerView) playerView.translatesAutoresizingMaskIntoConstraints = false playerView.bounds = videoCell.img_thumb.bounds playerView.center = videoCell.img_thumb.center playerView.centerXAnchor.constraint(equalTo: videoCell.img_thumb.centerXAnchor).isActive = true playerView.centerYAnchor.constraint(equalTo: videoCell.img_thumb.centerYAnchor).isActive = true playerView.heightAnchor.constraint(lessThanOrEqualTo: videoCell.img_thumb.heightAnchor).isActive = true playerView.widthAnchor.constraint(lessThanOrEqualTo: videoCell.img_thumb.widthAnchor).isActive = true
附Storyboard布局、约束设置及实际显示效果截图
PlayerView 完整代码
import Foundation import UIKit import AVKit class PlayerView: UIView { private var url: URL? private var urlAsset: AVURLAsset? private var playerItem: AVPlayerItem? var loaded: Bool = false var activityIndicator: UIActivityIndicatorView? private var assetPlayer:AVPlayer? { didSet { DispatchQueue.main.async { if let layer = self.layer as? AVPlayerLayer { layer.player = self.assetPlayer } } } } override class var layerClass: AnyClass { return AVPlayerLayer.self } init() { super.init(frame: .zero) initialSetup() } required init?(coder: NSCoder) { super.init(frame: .zero) initialSetup() } private func initialSetup() { if let layer = self.layer as? AVPlayerLayer { // Do any configuration layer.videoGravity = AVLayerVideoGravity.resizeAspect } } func prepareToPlay(withUrl url:URL, shouldPlayImmediately: Bool = false) { guard !(self.url == url && assetPlayer != nil && assetPlayer?.error == nil) else { if shouldPlayImmediately { play() } return } cleanUp() self.url = url let options = [AVURLAssetPreferPreciseDurationAndTimingKey : true] let urlAsset = AVURLAsset(url: url, options: options) self.urlAsset = urlAsset let keys = ["tracks"] urlAsset.loadValuesAsynchronously(forKeys: keys, completionHandler: { [weak self] in guard let strongSelf = self else { return } strongSelf.startLoading(urlAsset, shouldPlayImmediately) }) NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemDidReachEnd), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil) } private func startLoading(_ asset: AVURLAsset, _ shouldPlayImmediately: Bool = false) { var error:NSError? let status: AVKeyValueStatus = asset.statusOfValue(forKey: "tracks", error: &error) if status == AVKeyValueStatus.loaded { let item = AVPlayerItem(asset: asset) self.playerItem = item let player = AVPlayer(playerItem: item) self.assetPlayer = player self.loaded = true if shouldPlayImmediately { DispatchQueue.main.async { player.play() } } } } func toggle() { if self.assetPlayer?.isPlaying == false { play() } else { pause() } } func play() { guard self.assetPlayer?.isPlaying == false else { return } // if self.loaded && self.activityIndicator != nil { // self.activityIndicator?.stopAnimating() // } DispatchQueue.main.async { self.assetPlayer?.play() } } func pause() { guard self.assetPlayer?.isPlaying == true else { return } DispatchQueue.main.async { self.assetPlayer?.pause() } } func cleanUp() { pause() urlAsset?.cancelLoading() urlAsset = nil assetPlayer = nil NotificationCenter.default.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil) } deinit { cleanUp() } @objc private func playerItemDidReachEnd(_ notification: Notification) { guard notification.object as? AVPlayerItem == self.playerItem else { return } DispatchQueue.main.async { guard let videoPlayer = self.assetPlayer else { return } videoPlayer.seek(to: .zero) videoPlayer.play() } } }
内容的提问来源于stack exchange,提问作者Zach Handley
相关产品推荐
相关产品推荐

