TL;DR: 使用
scrollClipDisabled(true)
禁用裁剪(适用于 iOS 17+),或通过 Introspect 设置clipsToBounds = false
(适用于低版本),确保 SwiftUI ScrollView 完整显示内容,包括阴影和效果。
问题
在 SwiftUI 中,默认情况下,如果内容的尺寸(非滚动方向)超出 ScrollView 的边界,ScrollView 会对其进行裁切。如何禁止这种默认行为?
解决方案
1. 使用 scrollClipDisabled
(适用于 iOS 17+)
从 iOS 17 开始,SwiftUI 提供了 scrollClipDisabled
修饰符。将其设置为 true
,即可禁止 ScrollView 对超出尺寸的内容裁切。
Swift
struct ScrollClipDisableDemo: View {
@State private var disable = true
var body: some View {
VStack {
Toggle("Clip Disable", isOn: $disable)
.padding(20)
ScrollView {
ForEach(0 ..< 10) { i in
Rectangle()
.fill(.blue)
.frame(height: 100)
.shadow(color: .black, radius: 50)
.overlay(Text("\(i)").foregroundColor(.white))
}
}
}
.scrollClipDisabled(disable)
}
}
2. 使用 Introspect(适用于低版本 iOS)
Introspect 是一个第三方库,可用于访问底层 UIKit 对象。在低版本 iOS 中,可以通过 UIScrollView
的 clipsToBounds
属性禁用裁切行为。
Swift
import Introspect
struct ScrollClipDisableDemo: View {
@State private var disable = true
var body: some View {
VStack {
Toggle("Clip Disable", isOn: $disable)
.padding(20)
ScrollView {
ForEach(0 ..< 10) { i in
Rectangle()
.fill(.red)
.frame(height: 100)
.shadow(color: .black, radius: 50)
.overlay(Text("\(i)").foregroundColor(.white))
}
}
.introspect(.scrollView, on: .iOS(.v16, .v17, .v18)) { scrollView in
scrollView.clipsToBounds = !disable
}
}
.frame(width: 100)
}
}