SwiftUI教程:如何为macOS所有Button添加onHover效果
方案一:给 Button 扩展自定义修饰符(手动调用)
如果只想给部分 Button 添加效果,或者希望灵活控制,可给 Button 写个扩展,把悬停光标逻辑封装成自定义修饰符:
import SwiftUI extension Button { /// 添加鼠标悬停时显示手势光标的效果 func withHoverCursor() -> some View { self.onHover { isHovering in if isHovering { NSCursor.pointingHand.push() } else { NSCursor.pop() } } } }
使用时直接在 Button 后调用该方法:
Button("Hello World") { print("Hello World") } .withHoverCursor()
方案二:全局设置 ButtonStyle(自动生效)
如果要让应用内所有 SwiftUI Button 自动带上悬停光标效果,不用逐个调用方法,可自定义 ButtonStyle 并全局应用:
import SwiftUI // 自定义包含悬停光标效果的Button样式 struct HoverCursorButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .onHover { isHovering in if isHovering { NSCursor.pointingHand.push() } else { NSCursor.pop() } } // 保留系统默认Button样式,也可替换成自定义样式 .buttonStyle(.automatic) } } // 给ButtonStyle添加便捷访问入口 extension ButtonStyle where Self == HoverCursorButtonStyle { static var hoverCursor: HoverCursorButtonStyle { HoverCursorButtonStyle() } } // 在App入口全局设置该样式 @main struct YourAppName: App { var body: some Scene { WindowGroup { ContentView() .buttonStyle(.hoverCursor) } } }
注意事项
- 调用
NSCursor.push()后必须对应调用pop(),否则会导致光标状态异常 - 如果使用了自定义 ButtonStyle,要确保样式中的
.onHover不会被其他修饰符覆盖 - 以上方案仅适用于 SwiftUI 的
Button,如果是 AppKit 的NSButton,需通过 AppKit 原生方式处理(比如子类化或使用trackingArea)
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

