ios - 使用自定义过渡和自定义标识符时 SwiftUI 系统布局中断
问题描述
我在 Xcode 12.5.1 上的 SwiftUI 系统布局存在问题在文本视图上,我使用的是基于自定义 ViewModifiers 的自定义转换()。此外,我还使用了一个自定义的 id(),它允许我告诉系统这个 Text View 是不一样的,因此会触发一个过渡动画。
在视图上使用这两个修饰符时,其父级和内容本身不尊重系统布局的预期行为。您可以在此视频中确切看到发生了什么
这是我的示例项目代码,您可以自己测试:
import SwiftUI
struct ContentView: View {
private let contentArray: [String] = ["QWEQWE", "ASDASD", "TOTO", "FOO", "BAR"]
@State private var content: String = "content"
var body: some View {
VStack {
VStack {
Text(self.content)
// commenting either the transition modifier, or the id modifier, make the system layout work as expected. The problem comes from using both at the same time
.transition(.customTransition)
.id(self.content)
}
.background(Color.blue)
Button("action") {
guard let newValue = self.contentArray.randomElement() else {
print("Failed to get a random element from property contentArray")
return
}
withAnimation {
self.content = newValue
}
}
}
.background(Color.green)
}
}
extension AnyTransition {
static var customTransition: AnyTransition {
// uncomment the following line make the system layout work as expected. The problem comes from AnyTransition.modifier(active:identity:)
// return AnyTransition.slide.combined(with: .opacity)
let outAnimation = AnyTransition.modifier(active: CustomTrailingOffset(percent: 1), identity: CustomTrailingOffset(percent: 0)).combined(with: .opacity)
let inAnimation = AnyTransition.modifier(active: CustomLeadingOffset(percent: 1), identity: CustomLeadingOffset(percent: 0)).combined(with: .opacity)
return AnyTransition.asymmetric(insertion: inAnimation, removal: outAnimation)
}
}
struct CustomLeadingOffset: ViewModifier {
var percent: CGFloat = 0
func body(content: Content) -> some View {
GeometryReader { geo in
content.offset(CGSize(width: -geo.size.width*self.percent, height: 0.0))
}
}
}
struct CustomTrailingOffset: ViewModifier {
var percent: CGFloat = 0
func body(content: Content) -> some View {
GeometryReader { geo in
content.offset(CGSize(width: geo.size.width*self.percent, height: 0.0))
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.previewLayout(.device)
.previewDevice("iPhone 12")
}
}
在 Xcode 12.5.1 上测试
在我的研究过程中,我没有发现任何关于这种行为的信息,不是在博客文章中,不是在论坛上,也不是在官方文档中,这就是我在这里发布这个问题的原因,以防万一有人遇到这个问题,知道它为什么会发生,或者知道解决方案。我已经同时向 Apple 填写了一个雷达 (FB9605660),但我不确定我是否会被告知他们的结论。
解决方案
推荐阅读
- regex - 如何仅从数据中提取 IP?
- python - 如何在 Python 中为某些标签解析 XML 文件?
- laravel-6 - Laravel在开发windows时删除文件
- c# - 如何使用 Microsoft.Azure.Cosmos v3.9.1 从 CosmosDb 读取单个项目
- dictionary - 为什么我需要在 F# 中的这个字典初始值设定项中使用括号
- r - ggmap 的 mapdist() 函数有问题
- flutter - 我可以将 setState 仅用于一个小部件而不是整个页面吗?
- python - matplotlib dataframe 2 column [dates, non-numerical-data] 堆叠条形图定义属性
- logging - 如何在 CherryPy 启动之前设置应用程序 access_log 级别?
- javascript - Carousel Vue Awesome Swiper 有错误循环