Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SwiftUI:带动画条的步进器_Swiftui_Stepper_Uistepper - Fatal编程技术网

SwiftUI:带动画条的步进器

SwiftUI:带动画条的步进器,swiftui,stepper,uistepper,Swiftui,Stepper,Uistepper,我想创建一个带有动画条的步进器组件。以下是我得到的结果: 其想法是,该条应始终居中,而且我希望在值更改时设置蓝色条的动画,但我无法使其工作 这是我的密码: struct Stepper: View { @Binding var currentIndex: Int var total: Int var body: some View { ZStack(alignment: .center) { ZStack(alignme

我想创建一个带有动画条的步进器组件。以下是我得到的结果:

其想法是,该条应始终居中,而且我希望在值更改时设置蓝色条的动画,但我无法使其工作

这是我的密码:

struct Stepper: View {
    @Binding var currentIndex: Int
    var total: Int
    
    var body: some View {
        ZStack(alignment: .center) {
            ZStack(alignment: .leading) {
                Color.gray.opacity(0.4)
                Color.blue
                    .frame(width: 175.5 / CGFloat(total) * CGFloat(currentIndex))
            }
            .frame(width: 175.5, height: 2)
            Text("\(currentIndex)")
                .foregroundColor(.black)
                .offset(x: -113)
            Text("\(total)")
                .foregroundColor(.black)
                .offset(x: 113)
        }
        .frame(width: .infinity, height: 18)
    }
    
    init(withTotal total: Int,
         andCurrentIndex currentIndex: Binding<Int>) {
        self._currentIndex = currentIndex
        self.total = total
    }
    
    func update(to value: Int) {
        guard value >= 0, value <= total else {
            return
        }
        withAnimation {
            currentIndex = value
        }
    }
}
你能帮我理解为什么动画不起作用吗? 还有,有没有更好的方法来布局UI


谢谢大家!

最简单的解决方案是在
带动画的
块中更改
currentIndex
,如下所示:

Button(action: {
    withAnimation {
        currentIndex += 1
    }
}, label: {
    Text("INCREMENT")
})

这里是固定的步进器(使用Xcode 12.1/iOS 14.1测试)

struct步进器:视图{
@绑定变量currentIndex:Int
变量总计:Int
var body:一些观点{
ZStack(对齐:。中心){
ZStack(对齐:。引导){
颜色。灰色。不透明度(0.4)
蓝色
.框架(宽度:175.5/CGFloat(总计)*CGFloat(当前指数))
}
.框架(宽度:175.5,高度:2)

.animation(.default,value:currentIndex)/这里是固定的以步进器为中心的动画对齐方式。还添加了增量-减量值的验证。您现在可以在不使用更新函数的情况下以自己的方式使用它。目前,在您的代码中,这一行出现一条警告,这也得到了解决

 .frame(width: .infinity, height: 18)
最终代码:

struct Stepper: View {
    @Binding var currentIndex: Int
    
    private var total: Int
    
    private var mainIndex: Int {
        if currentIndex >= 0 && currentIndex <= total {
            return currentIndex
            
        } else if currentIndex < 0 {
            DispatchQueue.main.async {
                self.currentIndex = 0
            }
            return 0
            
        } else {
            DispatchQueue.main.async {
                self.currentIndex = total
            }
            return total
        }
    }
    
    var body: some View {
        GeometryReader { geometry in
            HStack() {
                Text("\(mainIndex)")
                    .foregroundColor(.black)
                    .frame(width: 30)
                
                ZStack(alignment: .leading) {
                    Color.gray.opacity(0.4).frame(width: geometry.size.width - 60)
                    Color.blue.frame(width: (geometry.size.width - 60) / CGFloat(total) * CGFloat(mainIndex))
                }
                .animation(.default, value: mainIndex)
                .frame(width: geometry.size.width - 60, height: 2)
                
                Text("\(total)")
                    .foregroundColor(.black)
                    .frame(width: 30)
            }
            .frame(width: geometry.size.width, height: geometry.size.height)
            .background(Color.yellow)
            
        }
    }
    
    init(withTotal total: Int,
         andCurrentIndex currentIndex: Binding<Int>) {
        self._currentIndex = currentIndex
        self.total = total
    }
    
    func update(to value: Int) {
        guard value >= 0, value <= total else {
            return
        }
        withAnimation {
            currentIndex = value
        }
    }
}

struct StepperVC: View {
    @State private var currentIndex: Int = 1
    
    var body: some View {
        VStack( alignment: .center,spacing: 32) {
            Stepper(withTotal: 8, andCurrentIndex: $currentIndex)
                .frame(width: UIScreen.main.bounds.size.width - 50, height: 50, alignment: .center)
            Button(action: {
                currentIndex += 1
            }, label: {
                Text("INCREMENT")
            })
            Button(action: {
                currentIndex -= 1
            }, label: {
                Text("DECREMENT")
            })
        }
    }
}
struct步进器:视图{
@绑定变量currentIndex:Int
私人变量总计:Int
私有索引:Int{
如果currentIndex>=0&¤tIndex=0,则为
 .frame(width: .infinity, height: 18)
struct Stepper: View {
    @Binding var currentIndex: Int
    
    private var total: Int
    
    private var mainIndex: Int {
        if currentIndex >= 0 && currentIndex <= total {
            return currentIndex
            
        } else if currentIndex < 0 {
            DispatchQueue.main.async {
                self.currentIndex = 0
            }
            return 0
            
        } else {
            DispatchQueue.main.async {
                self.currentIndex = total
            }
            return total
        }
    }
    
    var body: some View {
        GeometryReader { geometry in
            HStack() {
                Text("\(mainIndex)")
                    .foregroundColor(.black)
                    .frame(width: 30)
                
                ZStack(alignment: .leading) {
                    Color.gray.opacity(0.4).frame(width: geometry.size.width - 60)
                    Color.blue.frame(width: (geometry.size.width - 60) / CGFloat(total) * CGFloat(mainIndex))
                }
                .animation(.default, value: mainIndex)
                .frame(width: geometry.size.width - 60, height: 2)
                
                Text("\(total)")
                    .foregroundColor(.black)
                    .frame(width: 30)
            }
            .frame(width: geometry.size.width, height: geometry.size.height)
            .background(Color.yellow)
            
        }
    }
    
    init(withTotal total: Int,
         andCurrentIndex currentIndex: Binding<Int>) {
        self._currentIndex = currentIndex
        self.total = total
    }
    
    func update(to value: Int) {
        guard value >= 0, value <= total else {
            return
        }
        withAnimation {
            currentIndex = value
        }
    }
}

struct StepperVC: View {
    @State private var currentIndex: Int = 1
    
    var body: some View {
        VStack( alignment: .center,spacing: 32) {
            Stepper(withTotal: 8, andCurrentIndex: $currentIndex)
                .frame(width: UIScreen.main.bounds.size.width - 50, height: 50, alignment: .center)
            Button(action: {
                currentIndex += 1
            }, label: {
                Text("INCREMENT")
            })
            Button(action: {
                currentIndex -= 1
            }, label: {
                Text("DECREMENT")
            })
        }
    }
}