我正在为 tvOS 开发一款 SwiftUI 应用。我有一个带有图片和一行文本的 NavigationLink。该项目按预期工作,当聚焦时它会变大。但是,如果我更改圆角半径(默认值太大),那么即使圆角半径变小并且图片和文本变大,图片也会被剪裁(图片会变大但其边界保持不变)。我该如何解决这个问题?
NavigationStack {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
ForEach(sections) { section in
VStack(alignment: .leading, spacing: 20) {
// Section title
Text(section.title)
.font(.title)
.padding(.horizontal)
// Items
ScrollView(.horizontal) {
LazyHStack(spacing: 50) {
ForEach(section.items) { item in
NavigationLink {
VideoDetailView(mediaItem: item)
} label: {
AsyncImage(url: item.imageURL) { phase in
switch phase {
case .empty:
// This shows while the image is loading
ProgressView()
.aspectRatio(700/500, contentMode: .fit)
.containerRelativeFrame(.horizontal, count: 6, spacing: 50)
case .success(let image):
// This shows the successfully loaded image
image
.resizable()
.aspectRatio(700/500, contentMode: .fit)
.containerRelativeFrame(.horizontal, count: 6, spacing: 50)
case .failure(_):
// This shows if the image fails to load
Image(systemName: "photo")
.resizable()
.aspectRatio(700/500, contentMode: .fit)
.containerRelativeFrame(.horizontal, count: 6, spacing: 50)
@unknown default:
// Any other
EmptyView()
}
} .cornerRadius(5) // WHen I add this, the image gets clipped
Text(item.title)
//Text(item.subtitle)
}
.buttonStyle(.borderless)
}
}
}
.scrollClipDisabled()
}
}
}
}
}
当您应用 时
.cornerRadius
,实际上是在应用剪辑形状。事实上,修改器.cornerRadius
已弃用,您应该改用.clipShape
。为了避免您描述的裁剪效果,需要在链接获得焦点时发生的缩放效果之前应用角半径。但是,缩放效果是按钮样式中内置的,因此很难拦截。您还需要防止应用较大的角半径,否则您将看不到任何差异。角半径也
.borderless
内置在按钮样式中。.borderless
解决的一个方法是使用自定义的
ButtonStyle
,而不是.borderless
。缩放效果也需要内置到自定义按钮样式中。这需要知道链接何时获得焦点。
可以使用变量
FocusState
来检测链接何时具有焦点。如果您想模拟按钮样式的缩放效果
.borderless
,您会注意到只有图像被缩放,文本标签则不会。但是,标签会向下移动,与缩放后的图像保持大致相同的距离。为了能够对图像和文本应用不同的样式效果,可以将这两个元素包装为
Label
。然后自定义ButtonStyle
可以使用自定义LabelStyle
来执行样式。下面是一个简化的示例,展示了它如何以这种方式工作。我已经用静态图像替换了,但我希望当使用创建
AsyncImage
时,它应该可以正常工作。Label
AsyncImage
聚光灯效果
使用按钮样式时
.borderless
,还会将一种聚光灯效果应用于所选图像。如果您需要,这将是自定义标签样式可以添加到图像的另一种样式效果。实现该效果的一种方法是应用半透明
RadialGradient
(包括.white
).clear
作为覆盖。例如: