首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >即使是黑色背景SwiftUI,方向变化时的白光闪烁

即使是黑色背景SwiftUI,方向变化时的白光闪烁
EN

Stack Overflow用户
提问于 2022-03-28 08:34:40
回答 2查看 408关注 0票数 1

我有一个ZStack,我将颜色设置为黑色,然后添加一个VideoPlayer。当我旋转设备时,仍然有白色的闪光灯环绕着播放器。我玩过各种各样的想法和背景颜色,前景颜色,不透明度,没有什么是有效的。我只想背景是黑色的,所以它看起来像一个平稳的旋转。有人有什么建议或解决办法吗?这是我的密码:

代码语言:javascript
运行
复制
import Foundation
import SwiftUI
import AVKit

struct VideoDetail: View {
    
var videoIDString: String
var videoThumbURL: String
@State var player = AVPlayer()

var body: some View {
    
    ZStack {

        Color.black
            .edgesIgnoringSafeArea(.all)
        
        let videoURL: String = videoIDString

        VideoPlayer(player: player)
            //.frame(height: 200)
            .edgesIgnoringSafeArea(.all)
            .onAppear {
                
                player = AVPlayer(url: URL(string: videoURL)!)
                player.play()
            }
            .onDisappear {
                
                player.pause()
            }
    }
    .navigationBarHidden(true)
    .background(Color.black.edgesIgnoringSafeArea(.all))
    }
}
EN

回答 2

Stack Overflow用户

发布于 2022-05-14 02:11:09

我遇到了同样的问题,并遇到了一个解决方案:您可以设置宿主窗口的根视图控制器视图的背景色。您在SwiftUI中没有对此的直接访问,因此要做到这一点,可以使用this answer中描述的方法。

只需将withHostingWindow视图扩展(包括HostingWindowFinder )复制到某个地方,并在视图中使用以下代码将背景色设置为黑色:

代码语言:javascript
运行
复制
    var body: some View {
        ZStack {
            // ...
        }
        .withHostingWindow { window in
            window?.rootViewController?.view.backgroundColor = UIColor.black
        }
    }

这之后,白角旋转的时候就应该消失了!

票数 1
EN

Stack Overflow用户

发布于 2022-06-21 12:02:13

我感觉到你的痛苦。这是一个SwiftUI错误。SwiftUI当前的工作方式是它在UIKit视图中包含您的视图树。在大多数情况下,SwiftUI和UIKit合作得很好,但是有一个特别的领域似乎在同步UIKit和SwiftUI动画。

因此,当设备旋转时,实际上是UIKit驱动动画,所以SwiftUI必须最好地猜测它在动画曲线上的位置,但是它的猜测非常糟糕。

我们现在能做的最好的事情就是文件反馈。重复的bug报告是苹果如何优先处理的,所以每个人提交的bug报告越多越好。不一定要很久。将其命名为“设备旋转上的SwiftUI动画工艺品”,并编写“FB10376122的副本”作为描述,以引用有关同一主题的现有报告。

无论如何,在此期间,我们至少可以抓取包围窗口的UIKit视图,并将背景颜色设置在那里。这个解决方法是有限的,因为1)它不会改变上面提到的UIKit和SwiftUI动画之间的同步的明显‘跳跃’,并且只有当你的背景是块颜色时才会有帮助。

尽管如此,这里有一个WindowGroup替换和视图修饰符对,它将这个解决方案结合在一起,以尽可能好地与SwiftUI的其他部分一起使用。

示例用法:

代码语言:javascript
运行
复制
import SwiftUI

@main
struct MyApp: App {
    
    var body: some Scene {
        // Should be at the very top of your view tree within your `App` conforming type
        StyledWindowGroup {
            ContentView()
                // view modifier can be anywhere in your view tree 
                .preferredWindowColor(.black)
        }
    }
}

若要使用,请将以下内容复制到名为StyledWindowGroup.swift的文件中,并将其添加到项目中:

代码语言:javascript
运行
复制
import SwiftUI

/// Wraps a regular `WindowGroup` and enables use of the `preferredWindowColor(_ color: Color)` view modifier
/// from anywhere within its contained view tree. Use in place of a regular `WindowGroup`
public struct StyledWindowGroup<Content: View>: Scene {
    
    @ViewBuilder let content: () -> Content
    
    public init(content: @escaping () -> Content) {
        self.content = content
    }
    
    public var body: some Scene {
        WindowGroup {
            content()
                .backgroundPreferenceValue(PreferredWindowColorKey.self) { color in
                    WindowProxyHostView(backgroundColor: color)
                }
        }
    }
}

// MARK: - Convenience View Modifer

extension View {
    
    /// Sets the background color of the hosting window.
    /// - Note: Requires calling view is contained within a `StyledWindowGroup` scene
    public func preferredWindowColor(_ color: Color) -> some View {
        preference(key: PreferredWindowColorKey.self, value: color)
    }
}

// MARK: - Preference Key

fileprivate struct PreferredWindowColorKey: PreferenceKey {
    static let defaultValue = Color.white
    static func reduce(value: inout Color, nextValue: () -> Color) { }
}

// MARK: - Window Proxy View Pair

fileprivate struct WindowProxyHostView: UIViewRepresentable {
    
    let backgroundColor: Color
    
    func makeUIView(context: Context) -> WindowProxyView {
        let view = WindowProxyView(frame: .zero)
        view.isHidden = true
        return view
    }
    
    func updateUIView(_ view: WindowProxyView, context: Context) {
        view.rootViewBackgroundColor = backgroundColor
    }
}

fileprivate final class WindowProxyView: UIView {
    
    var rootViewBackgroundColor = Color.white {
        didSet { updateRootViewColor(on: window) }
    }
    
    override func willMove(toWindow newWindow: UIWindow?) {
        updateRootViewColor(on: newWindow)
    }
    
    private func updateRootViewColor(on window: UIWindow?) {
        guard let rootViewController = window?.rootViewController else { return }
        rootViewController.view.backgroundColor = UIColor(rootViewBackgroundColor)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71644516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档