You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在visionOS中自定义悬停效果区域

自定义SwiftUI按钮的悬停效果区域

在WWDC23的《为空间用户界面设计》视频约13:00处,Apple指出设计lock-up组件时需定义自定义区域以显示悬停效果,帮助用户识别完整交互元素,并保持组件间间距。参考Music App示例,我在应用中用LazyVGrid展示Button,已采用.plain按钮样式隐藏边框背景并保留悬停效果,但当前悬停效果为椭圆形,希望改为带额外内边距的圆角矩形,且悬停效果间保持4pt间距。尝试使用.contentShape(.hoverEffect, .rect(cornerRadius: 50).inset(by: -10))未生效,相关代码如下:

Button(action: tapAction) {
    VStack {
        Color.clear
            .background(.regularMaterial)
            .aspectRatio(1, contentMode: .fit)
            .clipShape(.rect(cornerRadius: 10))
            
        HStack(spacing: 0) {
            VStack(alignment: .leading, spacing: 0) {
                Text("Line one")
                
                Text("Line two")
                    .foregroundStyle(.secondary)
            }
            
            Spacer()
            
            MarkWateredButton(action: markWateredAction)
        }
    }
    .contentShape(.hoverEffect, .rect(cornerRadius: 50).inset(by: -10)) // FIXME: Doesn't do anything
}
.buttonStyle(.plain)

解决方案

问题核心是.contentShape的作用层级和参数设置错误,调整以下几点即可实现需求:

  • 调整.contentShape的绑定层级:将.contentShape从内部VStack移到Button本身,因为Button是交互触发容器,悬停效果的区域需要绑定到整个Button组件。
  • 修正形状参数:使用合适的圆角值(比如和内部视图一致的10),通过负数inset扩展悬停区域的内边距,数值可根据UI需求调整。
  • 设置LazyVGrid间距:在LazyVGrid的GridItem和容器本身设置spacing: 4,确保组件间悬停效果保持4pt间距。

修改后的完整代码示例:

// 配置LazyVGrid的间距
LazyVGrid(columns: [GridItem(.flexible(), spacing: 4)], spacing: 4) {
    Button(action: tapAction) {
        VStack {
            Color.clear
                .background(.regularMaterial)
                .aspectRatio(1, contentMode: .fit)
                .clipShape(.rect(cornerRadius: 10))
                
            HStack(spacing: 0) {
                VStack(alignment: .leading, spacing: 0) {
                    Text("Line one")
                    
                    Text("Line two")
                        .foregroundStyle(.secondary)
                }
                
                Spacer()
                
                MarkWateredButton(action: markWateredAction)
            }
        }
    }
    .buttonStyle(.plain)
    .contentShape(.hoverEffect, .rect(cornerRadius: 10).inset(by: -8)) // 绑定到Button层级
}

补充说明

  • 若需要更精细的区域控制,可以自定义Shape类型,或者结合.padding与基础形状来定义悬停范围。
  • 悬停效果的圆角值可根据设计需求自由调整,无需和内部视图圆角完全一致。

内容的提问来源于stack exchange,提问作者Jordan H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:25:03