CATextLayer不显示文本(仅显示背景色)



我发现了不同的帖子,人们在展示CATextLayer时遇到了这样或那样的问题。

不幸的是,线程的解决方案只对我部分有效。我的问题是,我的CATextLayer有时显示文本,有时不显示。

结构:我有一个AVSynchronizedLayer,在上面我添加了一个CATextLayer

为了便于说明,AVSynchronizedLayer具有黄色背景。CATextLayer具有红色背景,字体颜色为cyan

let synchronizedLayer = AVSynchronizedLayer(playerItem: playerItem)
synchronizedLayer.frame = CGRect(x: 0, y: 0, width: 500, height: 500)
synchronizedLayer.opacity = 1.0
synchronizedLayer.beginTime = 0.5
synchronizedLayer.backgroundColor = UIColor.yellow.cgColor

文本层:

let textlayer = CATextLayer()
textlayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
textlayer.fontSize = 20
let myAttributes = [
NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: 30.0)! , 
NSAttributedString.Key.foregroundColor: UIColor.cyan,                   
NSAttributedString.Key.backgroundColor: UIColor.red
]
let myAttributedString = NSAttributedString(string: "My text", attributes: myAttributes )
textlayer.alignmentMode = .center
textlayer.string = myAttributedString
textlayer.isWrapped = true
textlayer.beginTime = 1.0
textlayer.opacity = 1.0
textlayer.truncationMode = .end

我正在用层做什么

// playerItem is a bundle of 5 short movies (3 seconds long). Between every video is a opacity transition
let player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
// [...] config for playerLayer
synchronizedLayer.addSublayer(textlayer)
playerLayer.addSublayer(synchronizedLayer)        

return playerLayer // to the view   

我使用SwiftUI(iOS 15的最低版本(。但是SwiftUI不提供直接使用"AVPlayer"的可能性。我不得不建造一座桥。

struct CustomPlayerView: UIViewRepresentable {

let playerLayer: AVPlayerLayer
func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<CustomPlayerView>) {
}

func makeUIView(context: Context) -> UIView {
let customPlayerUIView = CustomPlayerUIView(frame: .zero)
customPlayerUIView.initPlayer(playerLayer: playerLayer)
return customPlayerUIView
}
}

initPlayer做以下事情

class CustomPlayerUIView: UIView {
private var playerLayer: AVPlayerLayer?

override init(frame: CGRect) {
super.init(frame: frame)
}

func initPlayer(playerLayer: AVPlayerLayer) {
self.playerLayer = playerLayer
layer.addSublayer(playerLayer)
playerLayer.player?.play()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
super.layoutSubviews()
}
}

总是出现一个黄色方框(AVSynchronizedLayer(和一个红色方框(CATextLayer(。只有文本总是随机显示。

我确信这是一个生命周期或渲染问题。但我不知道正确的生命周期是什么。我几乎在任何地方都已经调用了layoutIfNeeded()displayIfNeeded()。但这并没有起到任何作用。

结果1和结果2产生的代码相同。

主要问题似乎是这一行:

playerLayer.player?.play()

你显然是在玩家层准备好玩之前这么说的。(事实上,你甚至在播放器层进入窗口之前就已经说过了。(我在尝试播放之前等待了很长时间,从而使文本可靠地出现:

func initPlayer(playerLayer: AVPlayerLayer) {
self.playerLayer = playerLayer
layer.addSublayer(playerLayer)
Task { @MainActor in
try? await Task.sleep(nanoseconds: 5_000_000_000)
self.playerLayer?.player?.play()
}
}

恐怕我有点不清楚我们到底在等什么,但很明显,在(不管是什么(发生之前,我们不能比赛。你比我更了解你的代码,所以也许你可以弄清楚它是什么。

最新更新