HomeiOS Developmentmanagement how a View is moved/resized when its content material is simply...

management how a View is moved/resized when its content material is simply too massive?


I’ve create a StickyHeaderScrollView utilizing a ZStack to overlay MyScrollView with a header view.

MyScrollView is a UIViewControllerRepresentable holding an UIScrollView which permits setting the contentInset and supplies contentOffset updates on scrolling.

The StickyHeaderScrollView units the scroll contentInset to the defaultHeaderHeight, in order that the whole scroll content material is seen beneath the header. When the scroll view is scrolled up, the header view shrinks up till minHeaderHeight is reached. At this level the scroll content material begins to scroll beneath the header.

This works as meant, so long as the header content material isn’t bigger than minHeaderHeight. If so, the header content material ought to be clipped.

I management this?

As a substitute of this anticipated behaviour (clipping), the header view strikes up to create space for the content material.

Within the demo code beneath the defaultHeaderHeight is 200px and the minHeaderHeight is 100px. This works nice, so long as the header content material incorporates solely two 50px rects. However when a 3rd 50px rect is added, the content material peak of 150px exceeds the minHeaderHeight of 100px.

Whereas I perceive why this breaks the structure, I want to know if/how I can management how that is dealt with (clipping as an alternative of shifting).


management how a View is moved/resized when its content material is simply too massive?

struct StickyHeaderScrollView<Header: View, Physique: View>: View {
    let contentHeader: () -> Header
    let contentBody: Physique
    
    personal var minHeaderHeight: CGFloat
    personal var defaultHeaderHeight: CGFloat
    @State personal var headerHeight: CGFloat = 1
    
    init(
        headerHeight: CGFloat = 200,
        minHeaderHeight: CGFloat = 50,
        @ViewBuilder header: @escaping () -> Header,
        @ViewBuilder physique: () -> Physique
    ) {
        self.defaultHeaderHeight = headerHeight
        self.minHeaderHeight = minHeaderHeight
        
        self.contentHeader = header
        self.contentBody = physique()
    }
    
    
    var physique: some View {
        ZStack(alignment: .prime) {
            // MyScrollView is a UIViewControllerRepresentable holding an UIScrollView. Used
            // as an alternative of SwiftUI ScrollView have the ability to set the contentOffset and get
            // scroll place updates
            MyScrollView(
                content material: { contentBody },
                topContentOffset: defaultHeaderHeight,
                onScroll: { contentOffset in
                    self.headerHeight = max(minHeaderHeight, -contentOffset.y)
                }
            )
            .onAppear {
                headerHeight = defaultHeaderHeight
            }
            .ignoresSafeArea(edges: .backside)
            

            VStack(spacing: 0) {
                contentHeader()
            }
            .body(peak: headerHeight)
        }
    }
}


struct SomeView: View {
    var physique: some View {
        StickyHeaderScrollView(
            headerHeight: 200,
            minHeaderHeight: 100,
            header: {
                ZStack {
                    // Navbar
                    VStack {
                        HStack {
                            Button("Cancel") {}
                            Spacer()
                            Button("Save") {}
                        }
                        .padding(.prime)
                        .padding(.backside, 16)
                        .background(.inexperienced)
                    }
                    .body(maxHeight: .infinity, alignment: .prime)
                    .background(.yellow)
                    
                    
                    // Some Header Content material
                    // Complete peak: 3 rect * 50 = 150  >  minHeaderHeight: 100
                    VStack(spacing: 0) {
                        Rectangle().fill(.blue).body(width: 50, peak: 50)
                        Rectangle().fill(.purple).body(width: 50, peak: 50)
                        Rectangle().fill(.cyan).body(width: 50, peak: 50)
                    }
                    //.clipped() No impact
                }
                //.clipped() No impact + header background is now not robotically extendet into secure space
                .padding(.horizontal)
                .background(.grey)
            },
            physique: {
                VStack {
                    // Some ScrollContent
                    Colour.crimson.body(peak: 200)
                    Colour.blue.body(peak: 200)
                    Colour.inexperienced.body(peak: 200)
                    Colour.purple.body(peak: 200)
                    Colour.orange.body(peak: 200)
                }
            }
        )
    }
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments