SwiftUI-将视图从锚定到按钮框的按钮点击动画显示到屏幕上

SwiftUI-将视图从锚定到按钮框的按钮点击动画显示到屏幕上,swiftui,Swiftui,我创建了一个示例项目,用颜色显示视图布局。下面是它的样子: 下面是生成它的代码: struct ContentView:View{ @状态私有变量isShowingLeftPopup:Bool=false @国家私有变量isShowingRightPopup:Bool=false var body:一些观点{ TabView{ VStack{ 垫片() ZStack{ 颜色:红色 .框架(高度:200) HStack(间距:15){ 颜色 .disabled(self.isShowingRig

我创建了一个示例项目,用颜色显示视图布局。下面是它的样子:

下面是生成它的代码:

struct ContentView:View{
@状态私有变量isShowingLeftPopup:Bool=false
@国家私有变量isShowingRightPopup:Bool=false
var body:一些观点{
TabView{
VStack{
垫片()
ZStack{
颜色:红色
.框架(高度:200)
HStack(间距:15){
颜色
.disabled(self.isShowingRightPopup)
.ontapsigne{
self.isShowingLeftPopup.toggle()文件
}
颜色
.disabled(self.isShowingLeftPopup)
.ontapsigne{
self.isShowingRightPopup.toggle()文件
}
}
.框架(高度:70)
.padding(.卧式)
}
紫色
.框架(高度:300)
}
}
}
}
当点击两个蓝色矩形中的任何一个时,我想在蓝色矩形正下方的屏幕上设置视图动画,填充蓝色矩形和底部选项卡栏之间的垂直空间。动画目前并不那么重要——我不知道如何将条件视图锚定到蓝色矩形的底部,并调整其大小以适应下面剩余的空间

我制作了一个模型,模拟点击左蓝色矩形时的样子:


在本例中,我使用固定高度,但我正在寻找一种不依赖固定值的解决方案。有人知道如何将绿色矩形锚定到蓝色矩形的底部,并动态调整其大小以填充垂直空间直至选项卡栏吗?

您可以从GeometryReader、首选项和锚定参考中获益。我写了很多关于他们的文章。要了解有关其工作原理的更多信息,请参考:

GeometryReader文章:

首选项文章:

具体地说,对于您想要完成的任务,您需要知道蓝色视图和紫色视图(指示绿色视图的下限)的大小和位置。一旦你得到了这些信息,剩下的就很容易了。下面的代码正好可以做到这一点:

导入快捷界面
结构MyData{
让viewName:String
锚定
}
结构MyPreferenceKey:PreferenceKey{
静态变量defaultValue:[MyData]=[]
静态函数reduce(值:inout[MyData],nextValue:()->[MyData]){
append(contentsOf:nextValue())
}
typealias值=[MyData]
}
结构ContentView:View{
@状态私有变量isShowingLeftPopup:Bool=false
@国家私有变量isShowingRightPopup:Bool=false
var body:一些观点{
TabView{
VStack{
垫片()
ZStack{
颜色:红色
.框架(高度:200)
HStack(间距:15){
颜色
.disabled(self.isShowingRightPopup)
.ontapsigne{
self.isShowingLeftPopup.toggle()文件
}
.AnchorReference(键:MyPreferenceKey.self,值:.bounds){
返回[MyData(视图名称:“leftView”,边界:$0)]
}
颜色
.disabled(self.isShowingLeftPopup)
.ONTAPPORATE{self.isShowingRightPopup.toggle()}
.AnchorReference(键:MyPreferenceKey.self,值:.bounds){
返回[MyData(视图名称:“rightView”,边界:$0)]
}
}
.框架(高度:70)
.padding(.卧式)
}
紫色
.框架(高度:300)
.AnchorReference(键:MyPreferenceKey.self,值:.bounds){
return[MyData(视图名:“purpleView”,边界:$0)]
}
}.overlayPreferenceValue(MyPreferenceKey.self){中的首选项
GeometryReader{中的代理
团体{
如果self.isShowingLeftPopup{
ZStack(对齐:。顶部引导){
self.createRectangle(代理、首选项)
HStack{Spacer()}//使ZStack水平扩展
VStack{Spacer()}//使ZStack垂直扩展
}.frame(对齐:。顶部引线)
}否则{
EmptyView()
}
}
}
}
}
}
func createRectangle(geometry:GeometryProxy,preferences:[MyData])->一些视图{
让l=preferences.first(其中:{$0.viewName==“leftView”})
让r=preferences.first(其中:{$0.viewName==“rightView”})
让p=preferences.first(其中:{$0.viewName==“purpleView”})
设边界_l=l!=nil?几何[l!.bounds]:.0
设边界\u r=r!=nil?几何[r!.bounds]:.0
设边界p=p!=nil?几何[p!.bounds]:.0
返回圆角转角(拐角半径:15)
.填充(颜色.绿色)
.frame(宽度:bounds_r.maxX-bounds_l.minX,高度:bou