I found different posts where people have problems to show CATextLayer like this or that.
The solution from the threads unfortunately only partially work for me. My problem is that my CATextLayer sometimes show text and sometimes not.
The structure: I have an AVSynchronizedLayer, on this I add a CATextLayer.
For illustration the AVSynchronizedLayer has a yellow background. The CATextLayer has a red background with font color 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
The text layer:
        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
What I am doing with the layers
// 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   
I use SwiftUI (min version iOS 15). But SwiftUI does not offer the possibility to use an 'AVPlayer' directly. I had to build a kind of bridge.
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
    }
}
The initPlayer does the following thing
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()
    }
}
What always appears is a yellow box (AVSynchronizedLayer) and a red box (CATextLayer). Only the text is always displayed randomly.
I am quite sure it's a lifecycle or rendering problem. But I don't know exactly what the correct lifecycle is. I have almost everywhere already layoutIfNeeded() or displayIfNeeded() called. But this had no effect.