簡體   English   中英

CATextLayer 不顯示文本(只是背景顏色)

[英]CATextLayer does not show text (just background color)

我發現人們在展示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()

您顯然是在播放器層准備好播放之前說。 (實際上,您是在播放器層甚至在 window 中之前說的。)通過在嘗試播放之前等待任意長時間,我能夠使文本可靠地顯示:

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()
    }
}

恐怕我對我們實際上在等待什么有點模糊,但顯然我們不能玩,直到它(不管它是什么)發生。 你比我更了解你的代碼,所以也許你可以弄清楚它是什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM