如何在SwiftUI中来回切换视图的大小?

问题描述 投票:0回答:1

编辑:在Asperi的帮助下,我决定重写说明,以便通过简单的复制+粘贴代码更好地阐明问题。

在所有测试中的预期行为:轻击右上角的Present按钮时,红色矩形将使其大小从零动画化为父视图的大小。再次点击Present时,红色矩形将从父视图的尺寸缩小到零。


测试1的属性状态更改

实际行为:

按预期工作。

代码:

struct ContentView: View {  
    @State private var presentRedBox = false  

    var body: some View {  
        NavigationView {  
            GeometryReader { proxy in  
                ZStack {  
                    // ------  
                    Rectangle().fill(Color.red)  
                        .frame(  
                            width: self.presentRedBox ? proxy.size.width : 0.0,  
                            height: self.presentRedBox ? proxy.size.height : 0.0  
                        )  
                    // ------  
                }  
            }.animation(.default)  
            .navigationBarItems(trailing: Button("Present") { self.presentRedBox.toggle() })  
            .navigationBarTitle(Text(""), displayMode: .inline)  
        }  
    }  
}  

使用属性状态更改的测试#2动画/视图修改器

实际行为:

按预期工作。

代码:

extension AnyTransition {  
    static func sizeTransition(from: CGSize, to: CGSize) -> AnyTransition {  
        .modifier(  
            active: SizeTransition(size: from),  
            identity: SizeTransition(size: to)  
        )  
    }  
}  

struct SizeTransition: AnimatableModifier {  
    var size: CGSize  

    var animatableData: AnimatablePair<cgfloat, cgfloat=""> {  
        get { AnimatablePair(size.width, size.height) }  
        set {  
            size.width = newValue.first  
            size.height = newValue.second  
        }  
    }  

    func body(content: Content) -> some View {  
        print(size)  
        return content.frame(  
            width: size.width,  
            height: size.height  
        )  
    }  
}  

struct ContentView: View {  
    @State private var presentRedBox = false  

    var body: some View {  
        NavigationView {  
            GeometryReader { proxy in  
                ZStack {  
                    // ------  
                    Rectangle().fill(Color.red)  
                        .modifier(  
                            SizeTransition(  
                                size: self.presentRedBox ? proxy.size : .zero  
                            )  
                        )  
                    // ------  
                }  
            }.animation(.default)  
            .navigationBarItems(trailing: Button("Present") { self.presentRedBox.toggle() })  
            .navigationBarTitle(Text(""), displayMode: .inline)  
        }  
    }  
} 

测试#3具有过渡性的动画/视图修改器

实际行为:

红色的矩形将按预期进行动画处理。 但是(!)它将动画化,但立即消失,尽管日志显示正确的值。

登录动画

(0.0, 0.0) (1.8118343353271484, 3.3873424530029297) (7.392631530761719, 13.821006774902344) (16.9350643157959, 31.66120719909668) (30.5800838470459, 57.17146110534668) (48.38059616088867, 90.45067977905273) (70.25803184509277, 131.35197257995605) (95.95654678344727, 179.39702224731445) (124.99998664855957, 233.6956272125244) (156.67254066467285, 292.90953254699707) (190.03098106384277, 355.27531242370605) (223.97296714782715, 418.73206901550293) (257.33140754699707, 481.0978488922119) (289.00356674194336, 540.3110160827637) (318.04700660705566, 594.6096210479736) (343.7447319030762, 642.6531944274902) (365.6217727661133, 683.5537490844727) (383.42189025878906, 716.8322296142578) (397.06651496887207, 742.3417453765869) (406.60855293273926, 760.1812076568604) (412.18856048583984, 770.613395690918) (414.0, 774.0)

日志动画输出

(413.61268043518066, 773.2758808135986) (410.07547760009766, 766.6628494262695) (402.6749496459961, 752.8270797729492) (391.2381649017334, 731.4452648162842) (375.6612854003906, 702.3232727050781) (355.94628524780273, 665.4647941589355) (332.24832916259766, 621.1599197387695) (304.9215717315674, 570.070764541626) (274.5523223876953, 513.2934722900391) (241.9665470123291, 452.3722400665283) (208.19354438781738, 389.231409072876) (174.37908554077148, 326.0130729675293) (141.67486381530762, 264.870397567749) (111.12004852294922, 207.74617767333984) (83.55758285522461, 156.21635055541992) (59.59075355529785, 111.40880012512207) (39.58871841430664, 74.01369094848633) (23.71967124938965, 44.34547233581543) (11.994667053222656, 22.42481231689453) (4.315790176391602, 8.06865119934082) (0.5136623382568359, 0.9603252410888672) (0.0, 0.0)

代码:

extension AnyTransition { static func sizeTransition(from: CGSize, to: CGSize) -> AnyTransition { .modifier( active: SizeTransition(size: from), identity: SizeTransition(size: to) ) } } struct SizeTransition: AnimatableModifier { var size: CGSize var animatableData: AnimatablePair<cgfloat, cgfloat=""> { get { AnimatablePair(size.width, size.height) } set { size.width = newValue.first size.height = newValue.second } } func body(content: Content) -> some View { print(size) return content.frame( width: size.width, height: size.height ) } } struct ContentView: View { @State private var presentRedBox = false var body: some View { NavigationView { GeometryReader { proxy in ZStack { // ------ if self.presentRedBox { Rectangle().fill(Color.red) .transition( .modifier( active: SizeTransition(size: .zero), identity: SizeTransition(size: proxy.size) ) ) } // ------ } }.animation(.default) .navigationBarItems(trailing: Button("Present") { self.presentRedBox.toggle() }) .navigationBarTitle(Text(""), displayMode: .inline) } } }
编辑:在Asperi的帮助下,我决定重写描述,以便通过简单的复制+粘贴代码更好地阐明问题。所有测试的预期行为:红色矩形将根据...的大小为其动画,...
xcode animation swiftui transition anytransition
1个回答
1
投票
我知道这并不是您所要求的解决方案,但是在某些情况下可能有用,所以我决定将其发布。
© www.soinside.com 2019 - 2024. All rights reserved.