Thahir
Thahir

Reputation: 981

What is the SwiftUI equivalent of clipsToBounds?

I have a scrollview in SwiftUI for which I dont want to clip the contents which are out of bounds while scrolling. In UIKit, we can achieve this by setting clipsToBounds to false for the scrollview. How would you do the same in SwiftUI. Or what's the best practice to achieve a similar behavior in SwiftUI?

Btw I know we can use UIViewRepresentable to map UIKit view or if we use some libraries like SwiftUI-Introspect we can get the underlying UIKit scrollview and set clipsToBounds to false. But I'd like to know if there is a native SwiftUI way to do it.

This is some code which could make the question a bit more clear.

struct MyScrollView: View {
    var body: some View {
        VStack(spacing: 0) {
            header
            content
        }
    }
    
    var header: some View {
        Text("Header")
            .padding()
            .frame(minHeight: 200)
    }
    
    var content: some View {
        ScrollView {
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
        }
        .frame(maxWidth: .infinity)
        .background(.orange)
    }
} 

This is what it renders, scrollview content is clipped as I scroll up.

enter image description here

What I'm looking for is like this, I should be able to see content under the header as I scroll up.

enter image description here

Thanks in advance :)

Upvotes: 2

Views: 3442

Answers (2)

Lucas Lacerda
Lucas Lacerda

Reputation: 11

On iOS 17, SwiftUI has a view modifier called .scrollClipDisabled()

Before this version, you can do

public extension UIScrollView {
    override var clipsToBounds: Bool { 
        get { false } 
        set {}
    }
}

Upvotes: 1

Ptit Xav
Ptit Xav

Reputation: 3219

EDIT : Use a Stack and add an empty header to the scroll view:

struct MyScrollView: View {
    var body: some View {
        ZStack {
            content
            VStack {
                header
                Spacer()
            }
        }
    }
    
    var header: some View {
        Text("Header")
            .padding()
            .frame(minHeight: 200)
    }
    
    var content: some View {
        ScrollView {
            Spacer()
                .frame(height:200)
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
            Text("Content").padding()
        }
        .frame(maxWidth: .infinity)
        .background(.orange)
    }
}

Upvotes: 1

Related Questions