ios – Easy methods to resolve SwiftUI animation conflicts

0
14
ios – Easy methods to resolve SwiftUI animation conflicts


I constructed a customized picker that reveals the picker gadgets when tapped.
Now I am making an attempt to make use of two of these pickers in one other view that solely reveals the picker that the person is presently interacting with and hides the opposite one however there’s a glitch within the picker animation such that hiding the picker pauses for a second earlier than utterly disappearing.

Here’s a display recording of the behaviour – https://imgur.com/a/gItlRIt

Right here is the code under:

struct ConceptOptionsView: View {
    @State personal var aspectRatio: AspectRatio = .sixteenbynine
    @State personal var imageModel: ImageModel = .flux(.schnell)
    @State personal var decision: ImageResolution = .seventwenty
    @State personal var activePicker: ActivePicker? = nil
    
    enum ActivePicker {
        case mannequin
        case decision
    }
    
    var physique: some View {
        VStack(spacing: 0) {
            Rectangle()
                .fill(.grey.opacity(0.3))
                .body(top: 0.5)
                .body(maxWidth: .infinity)
            VStack(alignment: .main, spacing: 20) {
                
                HStack {
                    if activePicker == nil || activePicker == .mannequin {
                        PillSelectorView(
                            title: "Mannequin",
                            icon: "sparkle",
                            choice: $imageModel,
                            gadgets: ImageModel.pickerItems,
                            didBeginSelection: {
                                activePicker = .mannequin
                            },
                            didEndSelection: {
                                activePicker = nil
                            }
                        )
                        .transition(.transfer(edge: .main))
                    }
                    Spacer()
                    if activePicker == nil || activePicker == .decision {
                        PillSelectorView(
                            title: "Decision",
                            icon: "digital camera.metering.middle.weighted.common",
                            choice: $decision,
                            gadgets: ImageResolution.pickerItems,
                            didBeginSelection: { activePicker = .decision },
                            didEndSelection: { activePicker = nil }
                        )
                        .transition(.transfer(edge: .trailing))
                    }
                }
                
                Textual content("The choices you choose would be the place to begin if you need to generate a brand new picture")
                    .font(.footnote)
                    .foregroundStyle(.secondary)
                    .multilineTextAlignment(.middle)
                    .padding(.horizontal, 20)
            }
            .padding()
            Spacer()
        }
        .background(.ultraThinMaterial)
        .animation(.snappy, worth: activePicker)
    }
}
struct PillSelectorItem: Identifiable {
    let id = UUID()
    let worth: SelectionValue
    let title: String
    
    init(
        worth: SelectionValue,
        title: String
    ) {
        self.worth = worth
        self.title = title
    }
}

struct PillSelectorView: View {
    let title: String
    let icon: String
    @Binding var choice: SelectionValue
    let gadgets: [PillSelectorItem]
    var didBeginSelection: () -> Void
    var didEndSelection: () -> Void
    
    @State personal var isSelecting: Bool = false

    var physique: some View {
        VStack(alignment: .main, spacing: 5) {
            Textual content(title)
                .font(.caption.weight(.medium))
                .foregroundStyle(.secondary)
                .padding(.main, 10)
            HStack {
                Button {
                    withAnimation {
                        isSelecting.toggle()
                    }
                } label: {
                    HStack {
                        Picture(systemName: icon)
                            .imageScale(.small)
                        if !isSelecting {
                            Textual content(gadgets.first(the place: { $0.worth == choice })?.title ?? "Merchandise")
                                .font(.subheadline.weight(.medium))
                        }
                    }
                    .padding(.horizontal)
                    .padding(.vertical, 12)
                    .body(maxWidth: isSelecting ? 40 : .infinity)
                    .background(.grey.opacity(0.1), in: .rect(cornerRadius: 20))
                }
                .buttonStyle(.plain)

                if isSelecting {
                    ScrollView(.horizontal) {
                        HStack {
                            ForEach(gadgets) { merchandise in
                                Button {
                                    withAnimation {
                                        choice = merchandise.worth
                                        isSelecting = false
                                    }
                                } label: {
                                    Textual content(merchandise.title)
                                        .font(.footnote.weight(.medium))
                                        .foregroundStyle(
                                            merchandise.worth == choice ? .main : .secondary
                                        )
                                        .padding(.vertical, 10)
                                        .padding(.horizontal, 10)
                                        .overlay {
                                            Capsule()
                                                .fill(
                                                    merchandise.worth == choice ? .grey.opacity(0.1) : .clear
                                                )
                                                .stroke(
                                                    merchandise.worth == choice
                                                        ? .main : Coloration.grey.opacity(0.3), lineWidth: 1.0
                                                )
                                        }
                                }
                                .buttonStyle(.plain)
                            }
                        }
                    }
                    .scrollIndicators(.hidden)
                    .transition(.transfer(edge: .trailing))
                }
            }
        }
        .onChange(of: isSelecting) { oldValue, newValue in
            newValue ? didBeginSelection() : didEndSelection()
        }
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here