我创建了一个横幅修改器,从顶部显示横幅。这动画效果很好。然而,当我点击以关闭它时,它根本没有动画,只是隐藏,即使点击手势动作已经withAnimation包裹它。
struct BannerModifier: ViewModifier {
@Binding var model: BannerData?
func body(content: Content) -> some View {
content.overlay(
Group {
if model != nil {
VStack {
HStack(alignment: .firstTextBaseline) {
Image(systemName: "exclamationmark.triangle.fill")
VStack(alignment: .leading) {
Text(model?.title ?? "")
.font(.headline)
if let message = model?.message {
Text(message)
.font(.footnote)
}
}
}
.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.foregroundColor(.white)
.background(.red)
.cornerRadius(10)
.shadow(radius: 10)
Spacer()
}
.padding()
.animation(.easeInOut)
.transition(AnyTransition.move(edge: .top).combined(with: .opacity))
.onTapGesture {
withAnimation {
model = nil
}
}
.gesture(
DragGesture()
.onChanged { _ in
withAnimation {
model = nil
}
}
)
}
}
)
}
}
struct BannerData: Identifiable {
let id = UUID()
let title: String
let message: String?
}
Run Code Online (Sandbox Code Playgroud)
在点击手势中,我擦除了模型,但它没有动画。它只会立即隐藏。我怎样才能让它动画化,让它向上滑动,这与向下滑动显示的方式相反?如果我还可以使拖动手势具有交互性,这样我就可以像本机通知一样将其滑出,那就太好了。
Asp*_*eri 15
从层次结构中删除视图始终由容器进行动画处理,因此要修复修改器,需要将其应用于.animation某些辅助容器(注意:Group实际上并不是真正的容器)。
这是更正后的变体
struct BannerModifier: ViewModifier {
@Binding var model: BannerData?
func body(content: Content) -> some View {
content.overlay(
VStack { // << holder container !!
if model != nil {
VStack {
HStack(alignment: .firstTextBaseline) {
Image(systemName: "exclamationmark.triangle.fill")
VStack(alignment: .leading) {
Text(model?.title ?? "")
.font(.headline)
if let message = model?.message {
Text(message)
.font(.footnote)
}
}
}
.padding()
.frame(minWidth: 0, maxWidth: .infinity)
.foregroundColor(.white)
.background(Color.red)
.cornerRadius(10)
.shadow(radius: 10)
Spacer()
}
.padding()
.transition(AnyTransition.move(edge: .top).combined(with: .opacity))
.onTapGesture {
withAnimation {
model = nil
}
}
.gesture(
DragGesture()
.onChanged { _ in
withAnimation {
model = nil
}
}
)
}
}
.animation(.easeInOut) // << here !!
)
}
}
Run Code Online (Sandbox Code Playgroud)
使用 Xcode 12.1 / iOS 14.1 和测试视图进行测试:
struct TestBannerModifier: View {
@State var model: BannerData?
var body: some View {
VStack {
Button("Test") { model = BannerData(title: "Error", message: "Fix It!")}
Button("Reset") { model = nil }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.modifier(BannerModifier(model: $model))
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10721 次 |
| 最近记录: |