Карусель изображений с эффектом перехода с помощью swiftUI - PullRequest
0 голосов
/ 02 февраля 2020

Итак, я использую swiftUI почти с момента его выпуска и играю с ним. Тем не менее, я пытаюсь добавить в приложение новую функцию, которая не работает должным образом. Я хочу иметь карусель изображений (automati c, что означает изменение изображения после регулярного интервала) с эффектом перехода. После небольшого исследования я мог бы найти способ сделать это. Но это не собирается вместе. Вот мой код: SwipeImages.swift

    import SwiftUI
    struct SwipeImages:View{

    @State private var difference: CGFloat = 0
    @State private var index = 0

    let spacing:CGFloat = 10




    var timer: Timer{

        Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { (timer) in

            if self.index < images.count - 1{
                self.index += 1
            }
            else{
                self.index = 0
            }
        }
    }

    var body:some View{

        ContentView(imageData: images[self.index])
            .onAppear {
                let _ = self.timer
        }
    }

}

    public struct ImageData:Identifiable{
        public let id:Int
        let image:String
        let title:String
        let country:String
    }

        let images = [ImageData(id:0,image:"1a.jpg",title: "String1", country: "country1"),
                      ImageData(id:1,image:"2a.jpg",title: "String2", country: "country2"),
                      ImageData(id:2,image:"3a.jpg",title: "String3", country: "country3")]

ContentView.swift

    import SwiftUI


struct ContentView:View{

    let imageData:ImageData

    var transitionStyle:Int = 1

    var transition:AnyTransition{

        switch transitionStyle{

        case 0:
            return .opacity
        case 1:
            return .circular
        case 2:
            return .stripes(stripes:50,horizontal:true)
        default:
            return .opacity

        }
    }

    var body:some View{
        ZStack{


            Image(uiImage: UIImage(named: "\(imageData.image)")!)
                .resizable()
                .transition(self.transition)
                .overlay(
                    Rectangle()
                        .fill(LinearGradient(gradient: Gradient(colors: [.clear,.black]), startPoint: .center, endPoint: .bottom))
                        .clipped()
            )
                .cornerRadius(2.0)



            VStack(alignment: .leading) {

                    Spacer()
                Text("\(imageData.title)")
                        .font(.title)
                        .fontWeight(.semibold)
                        .foregroundColor(.white)
                Text(imageData.country)
                    .foregroundColor(.white)

                }
            .padding()
        }
        .shadow(radius:12.0)
        .cornerRadius(12.0)

    }
}


extension Image{
    func imageStyle(height:CGFloat) -> some View{
        let shape = RoundedRectangle(cornerRadius: 15.0)

        return self.resizable()
            .frame(height:height)
            .overlay(
                Rectangle()
                    .fill(LinearGradient(gradient: Gradient(colors: [.clear,.black]), startPoint: .center, endPoint: .bottom))
                .clipped()
            )
                .cornerRadius(2.0)
        .clipShape(shape)

    }
}


extension AnyTransition{

    static var circular: AnyTransition{
        get{
            AnyTransition.modifier(active: ShapeClipModifier(shape: CircleClipShape(pct:1)), identity: ShapeClipModifier(shape: CircleClipShape(pct:0)))
        }
    }

    static func stripes(stripes s:Int,horizontal isHorizontal:Bool) -> AnyTransition{

        return AnyTransition.asymmetric(insertion: AnyTransition.modifier(active: ShapeClipModifier(shape:StripeShape(insertion:true,pct:1,stripes:s,horizontal:isHorizontal)), identity:
            ShapeClipModifier(shape:StripeShape(insertion:true,pct:0,stripes:s,horizontal:isHorizontal))
            ), removal:AnyTransition.modifier(active:             ShapeClipModifier(shape:StripeShape(insertion:false,pct:1,stripes:s,horizontal:isHorizontal))
                , identity:
                ShapeClipModifier(shape:StripeShape(insertion:false,pct:0,stripes:s,horizontal:isHorizontal)))
        )
    }


}

struct ShapeClipModifier<S: Shape>: ViewModifier{
    let shape: S

    func body(content:Content) -> some View {
        content.clipShape(shape)
    }
}


struct StripeShape: Shape{

    let insertion: Bool
    var pct: CGFloat
    let stripes: Int
    let horizontal: Bool

    var animatableData: CGFloat{
        get{pct}

        set{pct = newValue}
    }

    func path(in rect:CGRect) -> Path{

        var path = Path()


        let stripeHeight = rect.height/CGFloat(stripes)


        for i in 0..<stripes{

            let iteratorValue = CGFloat(i)

                if insertion{

                    path.addRect(CGRect(x: 0, y: iteratorValue * stripeHeight, width: rect.width, height: stripeHeight * (1 - pct)))
                }
                else{
                    path.addRect(CGRect(x: 0, y: iteratorValue * stripeHeight + (stripeHeight * pct), width: rect.width, height: stripeHeight * (1 - pct)))
            }

        }

        return path

    }
}

struct CircleClipShape: Shape{

    var pct:CGFloat

    var animatableData: CGFloat{
        get{pct}

        set{pct = newValue}
    }

    func path(in rect: CGRect) -> Path {
        var path = Path()
        var bigRect = rect
        bigRect.size.width = bigRect.size.width * 2 * (1-pct)
        bigRect.size.height = bigRect.size.height * 2 * (1-pct)
        bigRect = bigRect.offsetBy(dx: -rect.width/2.0, dy: -rect.height/2.0)

        path = Circle().path(in: bigRect)

        return path
    }


}

MainView.swift

   import SwiftUI
struct MainView:View{
var body:some View{
VStack{
SwipeImages()
.padding()
}
}
}

Когда приложение запускается, изображения меняются после запланированного указанный интервал, т. е. 2 с, но требуемый переход, такой как полоса или круг, ничего, похоже, не вступает в действие. (Кроме того, я попытался применить обычные встроенные переходы, такие как слайд и прозрачность, даже если они не работают). Не могли бы вы помочь мне определить, что не так, или какие-либо другие альтернативы для достижения того же? Благодаря.

...