AppKit知识碎片: NSPopover.behavior

最近属实是睡不着系列,SwiftUI 精通之路的分享目前在搁置,因为目前自己在尝试开发自己的第一款软件,是壁纸类的 MacOS 应用程序,所以自己也在学习一些 AppKit框架,今天分享下这个 NSPopover.behavior 这个弹出层类的属性,它主要可以做什么!

在 macos 开发中,NSPopover 是一个类,允许你在应用程序的用户界面中显示浮动的弹出窗口。

.behavior 属性主要是用于控制弹出窗口的行为,特别是用户与其进行交互时的响应。

它主要有这几变量:.transient, .semitransient, .applicationDefined, .modal

1 .transient

  • 描述: 这种行为的弹出窗口将保持在用户的屏幕上,直到用户点击弹出窗口外的区域。

  • 使用场景: 当你希望弹出窗口只在用户需要时出现,而不干扰用户的工作流时,可以使用这种行为。比如,工具提示或辅助信息窗口。

注意: 这种类型的弹出窗口通常在用户与应用程序的其他部分进行交互时消失。

2 .semitransient

  • 描述: 这种行为的弹出窗口在用户点击窗口之外时不会立即消失。用户可以在窗口内和外部之间进行交互。

  • 使用场景: 如果你希望用户在与弹出窗口交互时能够不被打断,但仍然希望他们能够关闭它。

3 .applicationDefined:

  • 描述: 这种行为表示弹出窗口的行为由应用程序自定义。
  • 使用场景: 当你想根据应用的特定需求来定义弹出窗口的显示和消失行为时,可以使用这个选项。

4 .modal:

  • 描述: 这种行为的弹出窗口会阻止用户与应用的其他部分进行交互,直到弹出窗口被关闭。

  • 使用场景: 当你希望强制用户解决某个问题或提供某个输入时,可以使用这个选项。

下面示例案例展示如何创建一个 NSPopover 并且其行为设置为.transient

import AppKit

class AppDelegate: NSObject, NSApplicationDelegate {

    var popover: NSPopover!

    func applicationDidFinishLanuching(_ notification: Notification) {

        popover = NSPopover()

        popover.contentSize = NSSize(width: 300, height: 200)

        popover.behavior = .transient

        popover.contentViewController = NSViewController() 

    }

}

NSPopover.show(relativeTo positioningRect: NSRect, of positioningView: NSView, preferredEdge: NSRectEdge)

NSPopover.show(relativeTo:of:preferredEdge:)NSPopover 用来显示弹出窗口的方法。通过这个方法,你可以将 NSPopover 相对于某个视图显示出来,并决定箭头的位置。它的具体参数如下:

方法定义

func show(relativeTo positioningRect: NSRect, of positioningView: NSView, preferredEdge: NSRectEdge)

参数介绍

  1. relativeTo positioningRect: NSRect
popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY)
  1. of positioningView: NSView
  • 指定用于定位 NSPopover 的视图。NSPopover 会相对于该视图进行弹出,箭头会根据该视图的位置进行定位。

  • 例如传入一个 NSButton 或状态栏按钮,NSPopover 就会相对于该按钮显示。

  1. preferredEdge: NSRectEdge
  • 指定弹出层的箭头应该出现在视图的哪一边。这是 NSRectEdge 类型的枚举值,可选的边包括:

  • .minX:箭头出现在左边。

  • .maxX:箭头出现在右边。

  • .minY:箭头出现在视图的顶部(通常用于状态栏按钮弹出时)。

  • .maxY:箭头出现在视图的底部。

假设你有一个状态栏按钮,你希望弹出层从按钮上方弹出,带有指向按钮的箭头。你可以使用如下代码:


if let button = statusBarItem.button {

    popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY)

}

在这个例子中:

relativeTo: button.bounds 表示弹出层的位置相对于按钮的边界进行定位。

of: button 表示弹出层会在这个按钮附近弹出。

preferredEdge: .minY 表示弹出层的箭头应该指向按钮的顶部,弹出层会从按钮的上方出现。

以下是一个完整的示例,展示如何在状态栏按钮上方显示带有箭头的 NSPopover

class AppDelegate: NSObject, NSApplicationDelegate {

    var statusBarItem: NSStatusItem!

    var popoverWindow: NSPopover!

 
    func applicationDidFinishLaunching(_ notification: Notification) {

        createStatusBarSymbol()

        createPopoverWindow()

    }

 
    func createStatusBarSymbol() {

        statusBarItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.variableLength)

        let image = NSImage(systemSymbolName: "photo.stack.fill",accessibilityDescription: "")

        image?.size = NSSize(width: 25, height: 25)

        image?.isTemplate = true

        statusBarItem.button?.image = image

        statusBarItem.button?.action = #selector(handleStatusButton)

        statusBarItem.button?.target = self

    }


    func createPopoverWindow() {

        popoverWindow = NSPopover()

        popoverWindow.contentSize = NSSize(width: 300, height: 400)

        popoverWindow.behavior = .transient

        popoverWindow.contentViewController = NSHostingController(rootView: ContentView())

    }

  
    @objc
    func handleStatusButton() {

        if let button = statusBarItem.button {

            

            if popoverWindow.isShown {

                popoverWindow.performClose(nil)

            } else {

                popoverWindow.show(relativeTo: button.bounds, of: button,preferredEdge: .minY)

            }

        }

    }

}

在这个例子中,NSPopover 会从状态栏按钮的上方弹出,并带有指向该按钮的箭头。

对于 relativeTo 这个属性的通俗的解释:

relativeTo 参数指定的是弹出层相对于某个视图(比如按钮)的位置矩形,它帮助你定义 NSPopover 弹出的位置。简单来说,relativeTo 是告诉系统,弹出层应该“靠近”哪部分显示。

假设你有一个按钮(或其他视图),当用户点击这个按钮时,弹出层会显示出来。relativeTo 就是指 这个弹出层应该以按钮的哪个部分为参考位置。通常,这个矩形是按钮的大小和位置。你可以理解为:

  • relativeTo 相当于告诉系统:“我想让弹出层显示在这个按钮的旁边”。

  • 这个矩形(NSRect)定义了参考的区域,也就是 弹出层会靠近并与这个区域对齐。

通常,设置为 button.bounds, 表示弹出层相对于整个按钮区域弹出。

举个形象的例子:

想象有一张纸(button.bounds 就是纸的大小),你要在这张纸的旁边(或上面、下面)放一个盒子(就是 NSPopover)。relativeTo 就是这张纸的位置和大小,告诉系统你想让盒子放在纸的哪个方向。

  • 如果你说 relativeTo: button.bounds,系统会让弹出层出现在按钮附近,具体靠哪一边由 preferredEdge 决定,比如上方或下方。

  • preferredEdge 是决定弹出层箭头在哪边的参数,比如箭头指向按钮的顶部、左边、右边等。

popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY)

这段代码做的事情就是:

  • relativeTo: button.bounds:弹出层相对于按钮的整个区域进行定位(通常是弹出层出现在这个区域的上方、下方、左边或右边)。

  • preferredEdge: .minY:弹出层的箭头会在按钮的顶部,弹出层会从按钮的上方出现。

如果你换成 .maxY,弹出层就会从按钮的下方出现。

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21435,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?