【问题标题】:SwiftUI: Implementing Timer into CarouselViewSwiftUI:在 CarouselView 中实现定时器
【发布时间】:2020-03-30 14:56:21
【问题描述】:

我遵循了这个教程..https://www.youtube.com/watch?v=fB5MzDD1PZI&list=WL&index=32&t=0s

我正在尝试将计时器添加到它,因为它会自动转到下一张图像。有什么建议吗?谢谢。

这是我当前的代码,缺少一些代码,我不知道下一步该做什么。

 import SwiftUI

struct ContentView: View {

    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State var Counter = 0

    var body: some View {
        ZStack {
            VStack {
                Text("HELLOWORLD")
                VStack{
                    CarouselView(itemHeight: 400, views: [
                        AnyView(Text("1")),
                        AnyView(Text("2")),
                        AnyView(Text("3")),
                        AnyView(Text("4")),
                        AnyView(Text("5")),
                        AnyView(Text("6")),
                    ]).onReceive(timer) { _ in
                        if self.Counter > 0 {
                          self.Counter -= 1
                          //missing some code to move index of carousel to i+1
                        }
                      }
                }

                Button(action: {
                  self.Counter = 10
                  }) {
                    Text("RUN")
                  }
            }
        }
    }

    }

struct CarouselView: View {

    @GestureState private var dragState = DragState.inactive
    @State var carouselLocation = 0

    var itemHeight:CGFloat
    var views:[AnyView]


    private func onDragEnded(drag: DragGesture.Value) {
        print("drag ended")
        let dragThreshold:CGFloat = 200
        if drag.predictedEndTranslation.width > dragThreshold || drag.translation.width > dragThreshold{
            carouselLocation =  carouselLocation - 1
        } else if (drag.predictedEndTranslation.width) < (-1 * dragThreshold) || (drag.translation.width) < (-1 * dragThreshold)
        {
            carouselLocation =  carouselLocation + 1
        }
    }



    var body: some View {
        ZStack{
            VStack{

                ZStack{
                    ForEach(0..<views.count){i in
                        VStack{
                            Spacer()
                            self.views[i]
                                //Text("\(i)")

                            .frame(width:300, height: self.getHeight(i))
                            .animation(.interpolatingSpring(stiffness: 300.0, damping: 30.0, initialVelocity: 10.0))
                                .background(Color.white)
                            .cornerRadius(10)
                            .shadow(radius: 3)


                            .opacity(self.getOpacity(i))
                            .animation(.interpolatingSpring(stiffness: 300.0, damping: 30.0, initialVelocity: 10.0))
                            .offset(x: self.getOffset(i))
                            .animation(.interpolatingSpring(stiffness: 300.0, damping: 30.0, initialVelocity: 10.0))
                            Spacer()
                        }
                    }

                }.gesture(

                    DragGesture()
                        .updating($dragState) { drag, state, transaction in
                            state = .dragging(translation: drag.translation)
                    }
                    .onEnded(onDragEnded)

                )

                Spacer()
            }
            VStack{
                Spacer()
                Spacer().frame(height:itemHeight + 50)
                Text("\(relativeLoc() + 1)/\(views.count)").padding()
                Spacer()
            }
        }
    }

    func relativeLoc() -> Int{
        return ((views.count * 10000) + carouselLocation) % views.count
    }

    func getHeight(_ i:Int) -> CGFloat{
        if i == relativeLoc(){
            return itemHeight
        } else {
            return itemHeight - 100
        }
    }


    func getOpacity(_ i:Int) -> Double{

        if i == relativeLoc()
            || i + 1 == relativeLoc()
            || i - 1 == relativeLoc()
            || i + 2 == relativeLoc()
            || i - 2 == relativeLoc()
            || (i + 1) - views.count == relativeLoc()
            || (i - 1) + views.count == relativeLoc()
            || (i + 2) - views.count == relativeLoc()
            || (i - 2) + views.count == relativeLoc()
        {
            return 1
        } else {
            return 0
        }
    }

    func getOffset(_ i:Int) -> CGFloat{

        //This sets up the central offset
        if (i) == relativeLoc()
        {
            //Set offset of cental
            return self.dragState.translation.width
        }
            //These set up the offset +/- 1
        else if
            (i) == relativeLoc() + 1
                ||
                (relativeLoc() == views.count - 1 && i == 0)
        {
            //Set offset +1
            return self.dragState.translation.width + (300 + 20)
        }
        else if
            (i) == relativeLoc() - 1
                ||
                (relativeLoc() == 0 && (i) == views.count - 1)
        {
            //Set offset -1
            return self.dragState.translation.width - (300 + 20)
        }
            //These set up the offset +/- 2
        else if
            (i) == relativeLoc() + 2
                ||
                (relativeLoc() == views.count-1 && i == 1)
                ||
                (relativeLoc() == views.count-2 && i == 0)
        {
            return self.dragState.translation.width + (2*(300 + 20))
        }
        else if
            (i) == relativeLoc() - 2
                ||
                (relativeLoc() == 1 && i == views.count-1)
                ||
                (relativeLoc() == 0 && i == views.count-2)
        {
            //Set offset -2
            return self.dragState.translation.width - (2*(300 + 20))
        }
            //These set up the offset +/- 3
        else if
            (i) == relativeLoc() + 3
                ||
                (relativeLoc() == views.count-1 && i == 2)
                ||
                (relativeLoc() == views.count-2 && i == 1)
                ||
                (relativeLoc() == views.count-3 && i == 0)
        {
            return self.dragState.translation.width + (3*(300 + 20))
        }
        else if
            (i) == relativeLoc() - 3
                ||
                (relativeLoc() == 2 && i == views.count-1)
                ||
                (relativeLoc() == 1 && i == views.count-2)
                ||
                (relativeLoc() == 0 && i == views.count-3)
        {
            //Set offset -2
            return self.dragState.translation.width - (3*(300 + 20))
        }
            //This is the remainder
        else {
            return 10000
        }
    }


}


enum DragState {
    case inactive
    case dragging(translation: CGSize)

    var translation: CGSize {
        switch self {
        case .inactive:
            return .zero
        case .dragging(let translation):
            return translation
        }
    }

    var isDragging: Bool {
        switch self {
        case .inactive:
            return false
        case .dragging:
            return true
        }
    }
}

附言。对不起,误解了规则。我是 StackOverFlow 和 SwiftUI 的新手。谢谢你。

【问题讨论】:

  • 你试过什么?你遇到了什么问题?
  • 嗨河马,欢迎来到stackoverflow。请阅读stackoverflow.com/help/how-to-ask。这不是“我们为您编写代码”的平台,而是“我们帮助您编写代码”的平台。所以向我们展示您尝试过的代码...它应该可以运行并重现您的问题。
  • 请不要破坏您自己的帖子。当您在此处发帖时,您授予 SO 根据 CC-by SA 4.0 分发内容的权利。任何破坏行为都将被撤销。

标签: swiftui


【解决方案1】:

看看这个:

import SwiftUI

struct ContentView: View {

    @State var location : Int = 0

    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State var Counter = 0

    var body: some View {
        ZStack {
            VStack {
                Text("HELLOWORLD")
                VStack{
                    CarouselView(carouselLocation: self.$location, itemHeight: 400, views: [
                        AnyView(Text("1")),
                        AnyView(Text("2")),
                        AnyView(Text("3")),
                        AnyView(Text("4")),
                        AnyView(Text("5")),
                        AnyView(Text("6")),
                    ]).onReceive(timer) { _ in
                        if self.Counter > 0 {
                            self.Counter -= 1
                            //missing some code to move index of carousel to i+1
                        }
                    }
                }

                Button(action: {
                    self.Counter = 10
                    Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { (timer) in
                        self.location += 1

                    }
                }) {
                    Text("RUN")
                }
            }
        }
    }

}

struct CarouselView: View {

    @GestureState private var dragState = DragState.inactive
    @Binding var carouselLocation : Int

    var itemHeight:CGFloat
    var views:[AnyView]


    private func onDragEnded(drag: DragGesture.Value) {
        print("drag ended")
        let dragThreshold:CGFloat = 200
        if drag.predictedEndTranslation.width > dragThreshold || drag.translation.width > dragThreshold{
            carouselLocation =  carouselLocation - 1
        } else if (drag.predictedEndTranslation.width) < (-1 * dragThreshold) || (drag.translation.width) < (-1 * dragThreshold)
        {
            carouselLocation =  carouselLocation + 1
        }
    }



    var body: some View {
        ZStack{
            VStack{

                ZStack{
                    ForEach(0..<views.count){i in
                        VStack{
                            Spacer()
                            self.views[i]
                                //Text("\(i)")

                                .frame(width:300, height: self.getHeight(i))
                                .animation(.interpolatingSpring(stiffness: 300.0, damping: 30.0, initialVelocity: 10.0))
                                .background(Color.white)
                                .cornerRadius(10)
                                .shadow(radius: 3)


                                .opacity(self.getOpacity(i))
                                .animation(.interpolatingSpring(stiffness: 300.0, damping: 30.0, initialVelocity: 10.0))
                                .offset(x: self.getOffset(i))
                                .animation(.interpolatingSpring(stiffness: 300.0, damping: 30.0, initialVelocity: 10.0))
                            Spacer()
                        }
                    }

                }.gesture(

                    DragGesture()
                        .updating($dragState) { drag, state, transaction in
                            state = .dragging(translation: drag.translation)
                    }
                    .onEnded(onDragEnded)

                )

                Spacer()
            }
            VStack{
                Spacer()
                Spacer().frame(height:itemHeight + 50)
                Text("\(relativeLoc() + 1)/\(views.count)").padding()
                Spacer()
            }
        }
    }

    func relativeLoc() -> Int{
        return ((views.count * 10000) + carouselLocation) % views.count
    }

    func getHeight(_ i:Int) -> CGFloat{
        if i == relativeLoc(){
            return itemHeight
        } else {
            return itemHeight - 100
        }
    }


    func getOpacity(_ i:Int) -> Double{

        if i == relativeLoc()
            || i + 1 == relativeLoc()
            || i - 1 == relativeLoc()
            || i + 2 == relativeLoc()
            || i - 2 == relativeLoc()
            || (i + 1) - views.count == relativeLoc()
            || (i - 1) + views.count == relativeLoc()
            || (i + 2) - views.count == relativeLoc()
            || (i - 2) + views.count == relativeLoc()
        {
            return 1
        } else {
            return 0
        }
    }

    func getOffset(_ i:Int) -> CGFloat{

        //This sets up the central offset
        if (i) == relativeLoc()
        {
            //Set offset of cental
            return self.dragState.translation.width
        }
            //These set up the offset +/- 1
        else if
            (i) == relativeLoc() + 1
                ||
                (relativeLoc() == views.count - 1 && i == 0)
        {
            //Set offset +1
            return self.dragState.translation.width + (300 + 20)
        }
        else if
            (i) == relativeLoc() - 1
                ||
                (relativeLoc() == 0 && (i) == views.count - 1)
        {
            //Set offset -1
            return self.dragState.translation.width - (300 + 20)
        }
            //These set up the offset +/- 2
        else if
            (i) == relativeLoc() + 2
                ||
                (relativeLoc() == views.count-1 && i == 1)
                ||
                (relativeLoc() == views.count-2 && i == 0)
        {
            return self.dragState.translation.width + (2*(300 + 20))
        }
        else if
            (i) == relativeLoc() - 2
                ||
                (relativeLoc() == 1 && i == views.count-1)
                ||
                (relativeLoc() == 0 && i == views.count-2)
        {
            //Set offset -2
            return self.dragState.translation.width - (2*(300 + 20))
        }
            //These set up the offset +/- 3
        else if
            (i) == relativeLoc() + 3
                ||
                (relativeLoc() == views.count-1 && i == 2)
                ||
                (relativeLoc() == views.count-2 && i == 1)
                ||
                (relativeLoc() == views.count-3 && i == 0)
        {
            return self.dragState.translation.width + (3*(300 + 20))
        }
        else if
            (i) == relativeLoc() - 3
                ||
                (relativeLoc() == 2 && i == views.count-1)
                ||
                (relativeLoc() == 1 && i == views.count-2)
                ||
                (relativeLoc() == 0 && i == views.count-3)
        {
            //Set offset -2
            return self.dragState.translation.width - (3*(300 + 20))
        }
            //This is the remainder
        else {
            return 10000
        }
    }


}


enum DragState {
    case inactive
    case dragging(translation: CGSize)

    var translation: CGSize {
        switch self {
        case .inactive:
            return .zero
        case .dragging(let translation):
            return translation
        }
    }

    var isDragging: Bool {
        switch self {
        case .inactive:
            return false
        case .dragging:
            return true
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 2020-02-11
    • 1970-01-01
    相关资源
    最近更新 更多