見出し画像

SwiftUIでいこう! - WWDC23 ScrollView -1

参考動画を見ながらの実装、実行します。

Paging


まずはページングについて。要はページの切り替え。

struct ContentView: View {
    var body: some View {
        ScrollView (.horizontal){
            let colors:[Color] = [.red,.blue,.green,.yellow]
            
            LazyHStack(spacing:25){
                ForEach(colors,id:\.self){color in
                    RoundedRectangle(cornerRadius: 15)
                        .fill(color.gradient)
                        .frame(height: 200)
                        .padding(.horizontal)
                        .containerRelativeFrame(.horizontal)
                }
                
            }
            .scrollTargetLayout()
            
        }
        .scrollTargetBehavior(.viewAligned)
    }
}

.scrollTargetBehavior(.paging)

では中央に揃わない。" LazyHStack(spacing:0)"とすれば中央に揃う。

もしくは、中央揃えにしたい場合は

.scrollTargetBehavior(.viewAligned)

を使うとspacingに関係なく中央に揃う。

Reading Scroll Position

struct ContentView: View {
    
    @State private var scrollPosition:Color?
    
    var body: some View {
        GeometryReader{         
            let size = $0.size   
            ScrollView (.horizontal){
                let colors:[Color] = [.red,.blue,.green,.yellow]
                
                LazyHStack(spacing:25){
                    ForEach(colors,id:\.self){color in
                        RoundedRectangle(cornerRadius: 15)
                            .fill(color.gradient)
                            .frame(width:300,height: 200)  
                    }      
                }
                .padding(.horizontal,(size.width - 300) / 2)
                .scrollTargetLayout()
                
            }
            .scrollTargetBehavior(.viewAligned)
            
            .scrollPosition(id: $scrollPosition)
            
        }
        .frame(height: 200)
        
        .overlay(alignment: .bottom){
            if let scrollPosition{
                Text(scrollPosition == .red ? "Red" : "other color")
                    .offset(y:100)
            }
        }
    }
}


.overlay(alignment: .bottom){
        if let scrollPosition{
                Text(scrollPosition == .red ? "Red" : "other color")
                        .offset(y:100)
         }
}

の部分を変更していきます。ボタンを押すとyellow、黄色の四角のところへ移動します。

 .overlay(alignment: .bottom){
                Button("Scroll To Yellow"){
                    withAnimation(.snappy){
                        scrollPosition = .yellow
                    }
                }
                .offset(y:100)
        }


Scroll Transitions

struct ContentView: View {
    var body: some View {
        ScrollView(.vertical){
            LazyVStack{
                ForEach(1...30,id:\.self){ _ in
                    Rectangle()
                        .fill(.red.gradient)
                        .frame(height: 185)
                }
            }
        
        }
        .padding(.horizontal,30)
    }
}

ここからTransitionの実装です。 .frame(height: 185)以下に

 .scrollTransition(topLeading: .interactive, bottomTrailing:.interactive){view,phase in
                            view
                   .opacity(1 - (phase.value < 0 ? -phase.value : phase.value))

付け加えます。

.interactive

をいろいろ変えて好みにできます。.animatedなど

Custum Trasition

struct ContentView: View {  
  @State private var showView:Bool = false
    var body: some View {
        VStack {
            if showView{
                Rectangle()
                    .fill(.red.gradient)
                    .frame(width: 150,height: 150)
                    .transition(MyTransition())
            }
        
            }
        
        Button("show View"){
            withAnimation(.bouncy){
                showView.toggle()
            }
        }
       
    }
}

struct MyTransition:Transition {
    func body(content:Content,phase:TransitionPhase) -> some View{
    content
    }
}

ボタンを押すと変形しながら表示しますが、その変形の仕方を決める構造体をつくります。

struct MyTransition:Transition {
    func body(content:Content,phase:TransitionPhase) -> some View{
    content
            .rotation3DEffect(
                .init(degrees: phase.value * 90),
                                      axis: /*@START_MENU_TOKEN@*/(x: 0.0, y: 1.0, z: 0.0)/*@END_MENU_TOKEN@*/
            )
    }
}

これでボタンを押した時に表示され、もう一度押すとアニメーションして消える動作をつけることができます。

この記事が気に入ったらサポートをしてみませんか?