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

Jor*_*n H 4 hover swift visionos

在13:00 左右的 WWDC 空间用户界面设计视频中,Apple 对于悬停效果做了以下说明:

当您设计锁定时,请包括一个形状,该形状将允许系统在人们关注它时显示悬停效果。在这里,我们有一些图像,下面有文字。每个锁定都是一个单独的交互元素。您需要定义一个自定义区域,以便它可以在人们观看时变亮。这有助于他们了解整个区域是一个可以选择的元素。并记住在每个包含的形状之间保留小空间。

它们包括来自音乐应用程序的示例:

音乐应用截图1 音乐应用截图2

我想在我的应用程序中执行此操作,在 LazyVGrid 中显示按钮,但无法实现该结果。我知道您需要使用plain按钮样式来隐藏边框按钮的背景但保持悬停效果。虽然悬停效果显示为椭圆形,但我希望它是一个圆角矩形,周围有额外的填充,悬停效果之间有 4 pt 的间距,如上所示。如何才能做到这一点?我以为.contentShape(.hoverEffect, .rect(cornerRadius: 50))会自定义该区域,但它似乎没有改变任何东西。

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)
Run Code Online (Sandbox Code Playgroud)

我的应用程序的屏幕截图

Hid*_*oeg 6

是的,就像 YichenBman 说的,你确实需要.hoverEffect()。作为奖励。你的背景cornerRadius是10。所以外半径应该是20,填充量是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)
        }
    }
    .padding(10)
    .contentShape(.hoverEffect, .rect(cornerRadius: 20)) 
    .hoverEffect()
}
.buttonStyle(.plain)
Run Code Online (Sandbox Code Playgroud)