View SwiftUI如何获取自定义幻灯片转换的视图大小?

View SwiftUI如何获取自定义幻灯片转换的视图大小?,view,swiftui,size,transition,direction,View,Swiftui,Size,Transition,Direction,SwiftUI具有默认的幻灯片转换。转换(.slide)。它工作得很好,但只完成了一半。我的意思是,我必须滑动我的视图,然后将它们向后滑动(我需要动画向后)。由于无法设置幻灯片过渡的方向,我实现了一个自定义过渡。该实现非常简单,并且运行良好。但我无法获得视图大小来计算起点和终点偏移点 extension AnyTransition{ 静态功能幻灯片(方向:SlideModifier.direction)->AnyTransition{ .Symmetric(插入:。修饰符(活动:SlideMod

SwiftUI具有默认的幻灯片转换
。转换(.slide)
。它工作得很好,但只完成了一半。我的意思是,我必须滑动我的视图,然后将它们向后滑动(我需要动画向后)。由于无法设置幻灯片过渡的方向,我实现了一个自定义过渡。该实现非常简单,并且运行良好。但我无法获得视图大小来计算起点和终点偏移点

extension AnyTransition{
静态功能幻灯片(方向:SlideModifier.direction)->AnyTransition{
.Symmetric(插入:。修饰符(活动:SlideModifier(正偏移量:true,方向:direction)),标识:SlideModifier(正偏移量:nil,方向:direction)),
删除:。修改器(活动:SlideModifier(正偏移:false,方向):direction),标识:SlideModifier(正偏移:nil,方向:direction)))
}
}
内部结构滑块修改器:视图修改器{
让积极的补偿:布尔?
让方向:方向
let offsetSize:CGFloat=200//如何通过编程获得此值?
枚举方向{
表壳前导、顶部、尾部、底部
}
func正文(内容:内容)->某些视图{
开关方向{
案例.领导:
返回内容.offset(x:positiveOffset==nil?0:(positiveOffset!?offsetSize:-offsetSize))
案例顶部:
返回内容.offset(y:positiveOffset==nil?0:(positiveOffset!?offsetSize:-offsetSize))
案例.尾随:
返回content.offset(x:positiveOffset==nil?0:(positiveOffset!?-offsetSize:offsetSize))
案例底部:
返回content.offset(y:positiveOffset==nil?0:(positiveOffset!?-offsetSize:offsetSize))
}
}
}
我想定义与视图大小相等的偏移大小。我的实验表明,这就是标准幻灯片过渡的工作原理。我尝试使用
GeometryReader
PreferenceKey
获取大小。也许我做错了什么,但没用

下面是一个使用自定义转换的简单示例

struct ContentView:View{
@国家私有变量isShowingRed=false
var body:一些观点{
ZStack{
如果是红色的{
颜色:红色
.框架(宽:200,高:200)
.transition(.slide(方向:。尾部))
}否则{
蓝色
.框架(宽:200,高:200)
.transition(.slide(方向:。前导))
}
}
.ontapsigne{
动画片{
isShowingRed.toggle()
}
}
}
}

有几种方法可以获得视图的大小。在你的情况下,我假设你正在寻找屏幕大小。以下是实现这一目标的方法。请记住,我没有打开IDE来完全测试它,其中可能有语法问题。我将在打开IDE后更新我的答案

热端 习惯于使用内嵌条件,它将在处理Swift UI中的动画和视图时提供巨大帮助

someBool ? varIfTrue : varIfFalse
someValue == someTest ? varIfTrue : varIfFalse
//(boolCondition) ? (Value if True) : (Value If False)

//You can even chain them together, but be careful to keep it 
//organized if you do this.
someBool ? someBool2 ? val1 : val2 : someBool2 ? val3 : val4
原始屏幕尺寸

几何读取器 这一个有点混乱,因为它将获得它所在的视图。它还有一个属性,可以设置为忽略安全区域。如果使用此方法,将根据视图得到不同的响应

//Parent Views Matter with GeometryReader
var body: some View {
    GeometryReader { geometry in 
        //Use the geometry, full screen size.
    }.ignoresSafeAreaAndEdges(.all)
}

var body: someView {
    VStack {
        GeometryReader { geometry in
             //This will have only the size of the parent view.
             // Ex: 100x100 square.
        }
    }.frame(width: 100, height: 100)
}
向后设置动画 你制作动画的方式是可行的,但是这样做会给你一个“倒带”类型的效果

var body: some View {
    ZStack {
        if isShowingRed {
            Color.red
                .frame(width: 200, height: 200)
                .offset(isShowingRed ? 0 : 100)
                .animation(.spring()) //You can also use .default
        } else {
            Color.blue
                .frame(width: 200, height: 200)
                .offset(isShowingRed ? 100 : 0)
                .animation(.spring()) //You can also use .default

        }
    }
    .onTapGesture {
        withAnimation {
            isShowingRed.toggle()
        }
    }
}

UIScreen.main.bounds.someProperty将在不使用GeometryReader的情况下获得屏幕大小。此外,您还应该能够通过执行类似于
View()的操作来设置偏移量。偏移量(x:isOffScreen==true?UIScreen.main.bounds.size.width/2:0)
当您更改
isOffScreen
时,使用动画{isOffScreen.toggle()}
@laenhall:您试图解决问题的方式是错误的!您不需要读取每个动画中的大小,这是对cpu的滥用,您只需要每次午餐读取一次,并根据方向更新change@xTwisteDx如果我使用
UIScreen.main.bounds
,动画对象将在整个屏幕上移动。这种行为并不总是可以接受的。@swiftPunk你有什么建议吗?不幸的是,你的解决方案都没有解决我的问题。
var body: some View {
    ZStack {
        if isShowingRed {
            Color.red
                .frame(width: 200, height: 200)
                .offset(isShowingRed ? 0 : 100)
                .animation(.spring()) //You can also use .default
        } else {
            Color.blue
                .frame(width: 200, height: 200)
                .offset(isShowingRed ? 100 : 0)
                .animation(.spring()) //You can also use .default

        }
    }
    .onTapGesture {
        withAnimation {
            isShowingRed.toggle()
        }
    }
}