【问题标题】:Why does a SwiftUI Rectangle with opacity 0.0 render a grey rectangle on a transparent NSWindow?为什么不透明度为 0.0 的 SwiftUI Rectangle 在透明的 NSWindow 上呈现灰色矩形?
【发布时间】:2021-07-20 16:14:51
【问题描述】:

我有一个透明的NSWindow,其中包含一个Rectangles 的网格,其不透明度可以切换。当不透明度为 0.0 时,会呈现一个灰色矩形(见图),我希望在其中看到一个空白区域。

我尝试在所有父视图中将背景颜色修改为Color.clear(在整个代码中散布),但怀疑原因在其他地方 - 可能是由于透明窗口的行为方式,因为似乎也有 drop阴影和轮廓等。

注意: 在 opacity 1.0 和 0.0 之间切换的行为略有不同,所以想知道如果 opacity 0.0?

我的目标是macOS 11.1

我的NSWindow 是这样构造的:

class TransparentWindow: NSWindow {

    init(contentRect: NSRect, backing: NSWindow.BackingStoreType, defer flag: Bool) {
        super.init(contentRect: contentRect, styleMask: [.borderless, .fullSizeContentView], backing: .buffered, defer: false)
        
        ignoresMouseEvents = true
        titlebarAppearsTransparent = true
        titleVisibility = .hidden
        isOpaque = false
        backgroundColor = NSColor.clear
        level = .floating
        isMovable = false
        isReleasedWhenClosed = false
        orderFront(nil)

        toolbar?.isVisible = false
        
        // Hide the traffic icons (standard close, minimize, maximize buttons)
        standardWindowButton(.closeButton)?.isHidden = true
        standardWindowButton(.miniaturizeButton)?.isHidden = true
        standardWindowButton(.zoomButton)?.isHidden = true
        
        styleMask.insert(NSWindow.StyleMask.fullSizeContentView)
    }
}

和意见大致如下:

struct GridView : View {
    @EnvironmentObject var appStore : AppStore

    var body: some View {
        let columns: [GridItem] =
            Array(repeating: .init(.fixed(size), spacing: spacing), count: cols)
                
        LazyVGrid(columns: columns, spacing: spacing) {
            ForEach(appStore.items) { item in
                GridItemView(item: item)
                    .frame(width: size, height: size)
                    .background(Color.clear)
                    .border(Color.clear, width: 0.0)

            }
        }.padding(0)
        .fixedSize()
        .background(Color.clear)
    }
}

struct GridItemView : View {
    
    @EnvironmentObject var appStore : AppStore
    @ObservedObject var item: Item
    @State var opacity = 0.5
    
    var body: some View {
        
        GeometryReader { geometry in
            Rectangle()
                .fill(Color.white)
                .onReceive(appStore.$frame) { frame in
                    let newFrame = calculateItemRect(
                        frame: frame,
                        crop: geometry.frame(in: .global)
                    )
                    
                    if (!newFrame.equalTo(item.frame)) {
                        item.frame = newFrame
                    }
                }.onReceive(item.$toggle) { toggle in
                    if toggle {
                        opacity = 0.0
            
                        DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                            opacity = 0.5
                            item.toggle = false
                        }
                    }
                }.opacity(opacity)
        }.background(Color.clear)
    }
}

【问题讨论】:

    标签: swift macos swiftui nswindow


    【解决方案1】:

    原来我需要在NSWindow 实例上将hasShadow 属性设置为false

    class TransparentWindow: NSWindow {
    
            // ...
            hasShadow = false
            ignoresMouseEvents = true
            // ...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-30
      • 2016-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2012-11-23
      • 2014-11-11
      相关资源
      最近更新 更多