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()
}
}
}