编辑:在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的帮助下,我决定重写描述,以便通过简单的复制+粘贴代码更好地阐明问题。所有测试的预期行为:红色矩形将根据...的大小为其动画,...