如何在透明窗口中更改 NSView 的宽度

时间:2021-07-16 14:22:10

标签: swift macos

(Swift、macOS、故事板)

我在透明窗口中有一个 NSView

我在 viewDidLoad 中有这个。使窗口透明并使 NSView 变为蓝色:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.2){
    self.view.window?.isOpaque = false
    self.view.window?.backgroundColor = NSColor.clear
}
view1.wantsLayer = true
view1.layer?.backgroundColor = NSColor.green.cgColor

enter image description here

我想在单击按钮时使用代码更改宽度。 如果它有约束:

@IBAction func button1(_ sender: NSButton) {
    view1Width.constant = 74
}

我尝试了没有限制和不同方法来改变宽度。它们都给出了相同的结果:

view1.frame = NSRect(x:50, y:120, width:74, height:100)

enter image description here

但是旧形状所在的位置仍然有边框和阴影。为什么会发生,如何解决?

它只发生在特定情况下:

  • 如果窗口是透明的(和 macOS)
  • 我改变了宽度而不改变位置 y
  • 窗口必须处于活动状态。如果不是(如果我点击其他任何地方),它看起来应该是:更改后的 NSView 周围的阴影为绿色。

(我已经简化了案例以尝试找到解决方案。我创建了一个新文档并且只有此代码并且我确定没有其他元素)

1 个答案:

答案 0 :(得分:1)

由于窗口是透明的,您需要使阴影无效。

Apple 声明了 invalidateShadow()

<块引用>

使窗口阴影无效,以便根据当前窗口形状重新计算。

完整的独立测试程序

它以编程方式设置 UI,而不是使用故事板。除此之外,代码与您的示例非常接近。

注意这一行:

view.window?.invalidateShadow()

在 onChange 方法中。

import Cocoa

class ViewController: NSViewController {
    private let view1 = NSView()
    private let changeButton = NSButton()
    private var view1Width: NSLayoutConstraint?
        
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2){
            self.view.window?.isOpaque = false
            self.view.window?.backgroundColor = NSColor.clear
        }
        view1.wantsLayer = true
        view1.layer?.backgroundColor = NSColor.green.cgColor
    }
    
    @objc private func onChange() {
        view1Width?.constant += 32
        view.window?.invalidateShadow()
    }
    
    private func setupUI() {
        changeButton.title = "change"
        changeButton.bezelStyle = .rounded
        changeButton.setButtonType(.momentaryPushIn)
        changeButton.target = self
        changeButton.action = #selector(onChange)
        
        self.view.addSubview(view1)
        self.view.addSubview(changeButton)
        
        self.view1.translatesAutoresizingMaskIntoConstraints = false
        self.changeButton.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            view1.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            view1.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            view1.heightAnchor.constraint(equalToConstant: 128),
            
            changeButton.topAnchor.constraint(equalTo: view1.bottomAnchor, constant:16),
            changeButton.centerXAnchor.constraint(equalTo: view1.centerXAnchor)
        ])
        
        view1Width = view1.widthAnchor.constraint(equalToConstant: 128)
        view1Width?.isActive = true
    }

}

结果

更新阴影的预期结果已完成: shadow demo

相关问题