简体   繁体   中英

Horizontal Paging Scrollview with TabView, SwiftUI

I'm trying to make a 3 paged tabview with 3 images for each page. Paging is OK but tabview creates a vertical scroll for my images and pushes them to the bottom.

VStack{
                TabView(selection: $currentIndex.animation()) {
                    ForEach(0 ..< 3, id: \.self) {i in
                        VStack{
                            Image("wp\(i + 1)")
                        }.background(Color.blue)
                    }
                }.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)).background(Color.yellow)
            }

在此处输入图像描述

在此处输入图像描述

Any idea why that happens?

To make sure the view doesn't scroll you can limit the image sizes and let them resize to a certain height.

In the code below I use GeometryReader and Image modifiers to put as many images as you want per tab with no vertical scrollbar:

struct ContentView : View {
    @State var currentIndex:Int = 0
    @State var imagesPerTab:Int = 1
    
    var body: some View {
        GeometryReader { geo in
            
            // limit image height within 90% of tab height
            // this guarantees the images will not cause a vertical scroll
            let heightPerImage = (geo.size.height * 0.9) / CGFloat(imagesPerTab)
            
            VStack {
                // added a button to see effect of adding as many images as wanted
                Button(action:{imagesPerTab += 1}) {
                    Image(systemName:"plus.app")
                        .resizable()
                        .aspectRatio(contentMode:.fit)
                        .frame(height:geo.size.height * 0.05) // button can only be 5% of height
                }
                TabView(selection: $currentIndex.animation()) {
                    ForEach(0 ..< 3, id: \.self) {i in
                        
                        // tab
                        VStack(spacing:0) { // remove vertical spacing between images
                            ForEach(0 ..< imagesPerTab, id: \.self) {_ in
                                Image(systemName:"flame")
                                    .resizable() // image resize freely
                                    .aspectRatio(contentMode:.fit) // image doesn't skew
                                    .frame(height:heightPerImage) // limit image to this height
                            }
                        }
                        .background(Color.blue)
                    }
                }
                .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
                    .background(Color.yellow)
            }
        }
    }
}
  • By default in SwiftUi, Image is getting the actual image size. to resize it we have to make it resizable() before adding a frame() .
  • To get the dimensions which the view itself can get, GeometryReader is used.
  • tag is used to do the selection, so that the type of the selection variable and the type of tag parameter should be the same.

struct ContentView: View {
            
            @State var selection = 0
            var body: some View {
                VStack{
                    TabView (selection: $selection){
                        ForEach(0 ..< 3, id: \.self) {i in
                            VStack{
                                GeometryReader { proxy in //<- here
                                    Image(systemName: "pencil")
                                        .resizable()
                                        .aspectRatio(contentMode: .fit) //<- here
                                        .frame(width: proxy.size.width, height: proxy.size.height, alignment: .center) //<- here
                                        .tag(i) //to get selection
                                }
                            }.background(Color.blue)
                        }
                    }.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)).background(Color.yellow)
                }
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM