HomeiOS Developmentios - Collapsible header hides after pull-down gesture

ios – Collapsible header hides after pull-down gesture


I’m making an attempt to implement a collapsible header in SwiftUI that collapses when the consumer scrolls down and expands when the consumer scrolls up.

I adopted this Medium publish: Collapsible Header in SwiftUI

The implementation works high quality when scrolling usually, however I’ve run into an issue:

  • When the consumer drags the view down from the highest (pulls to refresh model) after which releases, the header disappears/hides unexpectedly.

Right here’s a brief display screen recording displaying the difficulty:
Display Recording

And right here is the code I’m utilizing:

public struct CollapsibleHeaderList: View {
    // MARK: - Personal Vars
    personal let gadgets = Array(0.. Bool {
        guard let lastAnimationDate else {
            return true
        }
        
        return abs(lastAnimationDate.timeIntervalSinceNow) > animationDuration
    }
}

public enum HeaderState {
    case preliminary
    case collapse
    case increase
}
public class CollapsibleHeaderViewModel: ObservableObject {
    @Printed personal(set) public var state: HeaderState
    personal var indexSubject = PassthroughSubject()
    personal var cancellables = Set()

    init() {
        self.state = .preliminary
        setupCollapsibleHeaderListener()
    }

    public func onCellAppear(index: Int) {
        indexSubject.ship(index)
    }

    personal func setupCollapsibleHeaderListener() {
        indexSubject
            .throttle(for: .seconds(0.5), scheduler: DispatchQueue.most important, newest: true)
            .withPrevious()
            .map { (earlier, present) in
                if let earlier, earlier  AnyPublisher {
        scan(Optionally available.none) { ($0?.1, $1) }
            .compactMap { $0 }
            .eraseToAnyPublisher()
    }
}

Query:
How can I forestall the header from hiding when the consumer pulls down from the highest?

Replace:

I attempted to implement the answer @Benzy Neez
advised, however now I get a bizarre shaking/jitter impact when the header seems. Additionally, when the view seems for the very first time, the header isn’t seen — it disappears instantly.

Right here is the display screen recording : Display recording 2

Right here is myCurrent code:

@State personal var showingHeader = true
    
    var physique: some View {
        ZStack {
            Colour.backgroundColor3
                .edgesIgnoringSafeArea(.all)
            VStack(spacing: 0) {
                if showingHeader {
                    GlobalContactsFilterView(viewModel: viewModel)
                        .body(top: 60)
                        .transition(
                            .uneven(
                                insertion: .push(from: .high),
                                elimination: .push(from: .backside)
                            )
                        )
                }
                
                if viewModel.isRefreshing {
                    VStack {
                        ProgressView()
                            .progressViewStyle(CircularProgressViewStyle())
                    }
                    .body(maxWidth: .infinity)
                    .padding(.high, 10)
                }
                
                if viewModel.contacts.isEmpty && !viewModel.isLoading && !viewModel.isRefreshing {
                    NoDataView()
                } else {
                    GeometryReader { outer in
                        let outerHeight = outer.measurement.top
                        ScrollView(.vertical) {
                            LazyVStack {
                                ForEach(Array(viewModel.contacts.enumerated()), id: .component.id) { index, contact in
                                    VStack(alignment: .main) {
                                        VStack {
                                            VStack(spacing: 12) {
                                                
                                                if contactVisibleFields.accommodates(.firstName) {
                                                    ContactDetailField(title: Strings.firstName, textual content: contact.firstName, textFont: .system(measurement: 13, weight: .semibold))
                                                }
                                                
                                                Rectangle()
                                                    .fill(.clear)
                                                    .body(maxWidth: .infinity, maxHeight: 1)
                                            }
                                            .padding(.high, 10)
                                        }
                                        .body(maxWidth: .infinity)
                                        .background(.backgroundColor2)
                                        .padding(.backside, 3)
                                    }
                                    .body(maxWidth: .infinity)
                                    .background(index == viewModel.contacts.rely - 1 ? Colour.clear : Colour.filterBarBackground)
                                    .padding(.backside, index == viewModel.contacts.rely - 1 ? 50 : 0)
                                    
                                }
                                .listRowBackground(Colour.clear)
                                .listRowInsets(EdgeInsets())
                                .listRowSeparator(.hidden)
                                
                                HStack {
                                    Spacer()
                                    if viewModel.isLoading && !viewModel.isRefreshing {
                                        ProgressView()
                                            .progressViewStyle(CircularProgressViewStyle())
                                    } else {
                                        Colour.clear
                                            .body(top: 1)
                                            .onAppear {
                                                if let _ = clerk.consumer {
                                                    viewModel.fetchContacts()
                                                }
                                            }
                                    }
                                    Spacer()
                                }
                                .body(maxWidth: .infinity)
                                .listRowSeparator(.hidden)
                                .listRowBackground(Colour.clear)
                            }
                            .background {
                                GeometryReader { proxy in
                                    let contentHeight = proxy.measurement.top
                                    let minY = max(
                                        min(0, proxy.body(in: .named("ScrollView")).minY),
                                        outerHeight - contentHeight
                                    )
                                    Colour.clear
                                        .onChange(of: minY) { oldVal, newVal in
                                            if (showingHeader && newVal  oldVal {
                                                showingHeader = newVal > oldVal
                                            }
                                        }
                                }
                            }
                        }
                        .coordinateSpace(title: "ScrollView")
                    }
                    .padding(.high, 1)
                }
            }
            //.body(maxHeight: .infinity, alignment: .high)
            .animation(.easeInOut, worth: showingHeader)

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments