您好,我正在try 一个快速的用户界面过渡,可以点击一个按钮,当视图2从顶部向下滑到屏幕上时,视图1将从屏幕底部向下滑动.如果显示了视图2,则当视图1从屏幕底部向上滑动时,视图2将向上滑出屏幕顶部.我try 使用自定义过渡来执行此操作,但这些都不起作用.在动画中包装布尔值更改也不起作用.我怎么才能解决这个问题呢?

import SwiftUI

extension AnyTransition {
    static var moveOne: AnyTransition {
        AnyTransition
            .asymmetric(
                insertion: .move(edge: .bottom),
                removal: .move(edge: .top)
            )
    }
    static var moveTwo: AnyTransition {
        AnyTransition
            .asymmetric(
                insertion: .move(edge: .top),
                removal: .move(edge: .bottom)
            )
    }
}

struct SwiftUIView: View {
    @State var show = true
    var body: some View {
        if !show {
            Rectangle().fill(.red.gradient).frame(width: widthOrHeight(width: true) * 0.8, height: widthOrHeight(width: false)).transition(.moveOne)
                .onTapGesture {
                    show.toggle()
                }
        } else {
            Rectangle().fill(.blue.gradient).frame(width: widthOrHeight(width: true) * 0.8, height: widthOrHeight(width: false)).transition(.moveTwo)
                .onTapGesture {
                    show.toggle()
                }
        }
    }
}

func widthOrHeight(width: Bool) -> CGFloat {
    let scenes = UIApplication.shared.connectedScenes
    let windowScene = scenes.first as? UIWindowScene
    let window = windowScene?.windows.first
    
    if width {
        return window?.screen.bounds.width ?? 0
    } else {
        return window?.screen.bounds.height ?? 0
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

推荐答案

你误解了什么是asymmetric%的过渡.

蓝色视图的过渡是:

  • 消失时向下移动
  • 显示时向上移动

红色视图的过渡为:

  • 消失时向上移动
  • 显示时向下移动

这些完全是symmetric--显示的视图的动画与消失的视图的动画正好相反!

因此,您所需要做的就是传递视图在appearing时应该做什么,对称性会自动计算出它在消失时应该做什么.红色视图向下移动,蓝色视图向上移动.

withAnimation包起来,你会得到:

if !show {
    Rectangle().fill(.red)
        .frame(...)
        .transition(.move(edge: .bottom))
        .onTapGesture {
            withAnimation {
                show.toggle()
            }
        }
} else {
    Rectangle().fill(.blue)
    .frame(...)
    .transition(.move(edge: .top))
        .onTapGesture {
            withAnimation {
                show.toggle()
            }
        }
}

顺便说一句,我不建议这样计算框架.试着找到一种更快捷的方式来做你脑海中的任何布局.

Swift相关问答推荐

字符串目录不适用于SWIFT包

SwiftUI:使视图B与视图A具有相同宽度的视图A更改比率?

如何在自定义视图中读取修改符子元素?

仅当单击UIButton时才调用计时器函数

在Xcode SWIFT中运行用Ionic编写的函数

如何通过 Enum 属性使用新的 #Predicate 宏获取

是否可以限制 ExpressibleByIntegerLiteral struct 的初始值?

为什么我在我的 Swift iOS 应用程序项目中收到 Xcode 中的错误消息无法识别的 Select 器发送到类?

是否可以使用 .task 修饰符更新基于两个值的视图

在 Vapor 4 中使用协议的通用流利查询

Swift 全局函数列表

Vapor 4 身份验证问题 [用户未通过身份验证]

如何以快速 Select 器菜单样式调整图像大小

为什么更改属性后动画会加速? SwiftUI

获取设备图像比例(例如@1x、@2x 和@3x)

如何为多个类 Swift 进行扩展

在 UItextfield 的右视图上添加一个按钮,文本不应与按钮重叠

在 Swift 中以编程方式更新约束的常量属性?

使用 ARAnchor 插入 node 和直接插入 node 有什么区别?

应用程序包不包含有效标识符