首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于选择值SwiftUI的背景图像动画

基于选择值SwiftUI的背景图像动画
EN

Stack Overflow用户
提问于 2021-03-05 06:34:27
回答 2查看 170关注 0票数 0

我有一个相当简单的视图,背景图像和选择器。我想根据当前选定的值更改背景图像。下面的代码可以工作,但是图像更改的动画缺少了--知道为什么吗?

代码语言:javascript
运行
复制
@State private var pickerIndex = 0
@State private var currentBackgroundImage = "fitness-1"

var body: some View {
        ZStack {
            Image(currentBackgroundImage)
                .resizable()
                .aspectRatio(contentMode: .fill)
                .transition(.opacity)
                .edgesIgnoringSafeArea(.all)
            
            VStack(spacing: 20) {
                    
                    Picker(selection: $pickerIndex, label: Text("")) {
                        Image("img1")
                            .tag(0)
                        Image("img2")
                            .tag(1)
                    }
                    .onChange(of: genderPickerIndex, perform: { value in
                        if(value == 0) {
                            withAnimation {
                                currentBackgroundImage = "fitness-1"
                            }
                        } else {
                            withAnimation {
                                currentBackgroundImage = "fitness-2"
                            }
                        }
                    })
                    .frame(width: 100)
                    .pickerStyle(SegmentedPickerStyle())
            }
        }
    }

编辑:

它似乎与选择无关-我只是用一个按钮替换它,图像变化仍然没有动画。我是不是在图像上少了一些修饰符?

代码语言:javascript
运行
复制
ZStack {
    Image(currentBackgroundImage)
        .resizable()
        .aspectRatio(contentMode: .fill)
        .transition(.opacity)
        .edgesIgnoringSafeArea(.all)
           
    Button(action: {
        withAnimation {
            currentBackgroundImage = "fitness-2"
        }
    }) {
        Text("Change Image")
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-03-07 08:11:53

好的,为了获得我想要的动画,我创建了一个额外的组件:

代码语言:javascript
运行
复制
struct ImageSwitcher: View {
    
    let firstImage: String
    let secondImage: String
    
    @Binding var firstImageShowing: Bool
    
    var body: some View {
        ZStack {
            Image(firstImage)
                .resizable()
                .aspectRatio(contentMode: .fill)
                .edgesIgnoringSafeArea(.all)
                .opacity(firstImageShowing ? 1 : 0)
                .transition(.move(edge: .trailing))
                .animation(.easeInOut(duration: 0.17))
                .isHidden(!firstImageShowing)
               
            Image(secondImage)
                .resizable()
                .aspectRatio(contentMode: .fill)
                .edgesIgnoringSafeArea(.all)
                .opacity(firstImageShowing ? 0 : 1)
                .transition(.move(edge: .leading))
                .isHidden(firstImageShowing)
                .animation(.easeInOut(duration: 0.17))
        }
    }
}

.isHidden修饰符是一个扩展,用于根据状态变量隐藏图像。您可以在本文中看到更多详细信息:Dynamically hiding view in SwiftUI

很明显,您可以修改转换,但是我最终使用转换和不透明修饰符进行移动和淡入/淡出。

用法:

创建状态变量:

代码语言:javascript
运行
复制
@State private var showFirst = true

然后将它连同图像名称一起交给组件:

代码语言:javascript
运行
复制
ImageSwitcher(firstImage: "img-1", secondImage: "img-2", firstImageShowing: $showFirst)
票数 -1
EN

Stack Overflow用户

发布于 2021-03-05 07:41:53

选择器选择的类型为String,选择器数据的类型为Text,因此不会调用onChange修饰符。选择器选择类型和content类型必须相同,链接Picker in SwiftUI works with one version of ForEach, but not the other - a bug, or expected behavior?中的@Asperi也解释了这一点。相反,您可以使用forEach并循环您的[string]名称。

代码语言:javascript
运行
复制
struct ContentViewsss:View{
    var images = ["ABC","CDF"]
    @State private var pickerValue = "ABC"
    @State private var currentBackgroundImage = "ABC"
    
    var body: some View {
        VStack {
            Image(currentBackgroundImage)
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: 150, height: 150)
                .clipShape(Circle())
                .edgesIgnoringSafeArea(.all)
                .transition(.opacity)
            
            Picker(selection: $pickerValue, label: Text("")) {
                ForEach(images,id:\.self) { imageName in
                    Text("\(imageName)")
                }
            }
            .onChange(of: pickerValue, perform: { value in
                
                self.changeBackgroundImage(value)
            })
            .frame(width: 200)
            .pickerStyle(SegmentedPickerStyle())
            
        }
    }
    
    func changeBackgroundImage(_ value: String) {
        switch value {
        case "ABC":
            withAnimation {
                currentBackgroundImage = "ABC"
            }//the app changes the image, but the "withAnimation" does not seem to do anything
        
        case "CDF":
            withAnimation {
                currentBackgroundImage = "CDF"
            }//the app changes the image, but the "withAnimation" does not seem to do anything
        
        default:
            currentBackgroundImage = "landing-page"
        }
        
    }
}

或者您可以在newValue内部直接分配onChange,而不是单独的函数。

代码语言:javascript
运行
复制
struct ContentViewsss:View{
    var images = ["ABC","CDF"]
    @State private var pickerValue = "ABC"
    @State private var currentBackgroundImage = "ABC"
    
    var body: some View {
        VStack {
            Image(currentBackgroundImage)
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: 150, height: 150)
                .clipShape(Circle())
                .edgesIgnoringSafeArea(.all)
                .transition(.opacity)
            
            Picker(selection: $pickerValue, label: Text("")) {
                ForEach(images,id:\.self) { imageName in
                    Text("\(imageName)")
                }
            }
            .onChange(of: pickerValue, perform: { value in
           withAnimation {
                currentBackgroundImage = value
             } 
                //self.changeBackgroundImage(value)
            })
            .frame(width: 200)
            .pickerStyle(SegmentedPickerStyle())
            
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66487867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档