2

I have a View that contains a HStack and a DatePicker. When you tap on the HStack, the DatePicker is shown / hidden. I want to animate this action like the animation of Starts and Ends row in iOS Calendar's New Event View.

struct TimePicker: View {
    @Binding var startTime: Date
    
    @State private var isDatePickerVisible: Bool = false
    
    var body: some View {
        VStack(alignment: .center) {
            HStack {
                ListItemView(icon: "start-time",
                             leadingText: "Start Time",
                             trailingText: startTime.stringTime())
            }
            .onTapGesture {
                withAnimation {
                    self.isDatePickerVisible.toggle()
                }
            }
            
            Group {
                if isDatePickerVisible {
                    DatePicker("", selection: $startTime, displayedComponents: [.hourAndMinute])
                        .datePickerStyle(WheelDatePickerStyle())
                }
            }
            .background(Color.red)

            .modifier(AnimatingCellHeight(height: isDatePickerVisible ? 300 : 0))
        }
    }
}

I have used the following code for animation. It almost works. The only problem is that HStack jumps. And I can not fix it.

https://stackoverflow.com/a/60873883/8292178

struct AnimatingCellHeight: AnimatableModifier {
    var height: CGFloat = 0

    var animatableData: CGFloat {
        get { height }
        set { height = newValue }
    }

    func body(content: Content) -> some View {
        content.frame(height: height)
    }
}

How to fix this issue? How to animate visibility of the DatePicker?

1 Answer 1

1

It's simple, you don't need extra ViewModifier

    struct TimePicker: View {
        @Binding var startTime: Date
        @State private var isDatePickerVisible: Bool = false
        
        var body: some View {
            VStack(alignment: .center) {
                HStack {
                    ListItemView(icon: "start-time"
                         , leadingText: "Start Time"
                         , trailingText: startTime.stringTime())
                }.onTapGesture {
                    isDatePickerVisible.toggle()
                }
                
                if isDatePickerVisible {
                    DatePicker(""
                         , selection: $model.startTime
                         , displayedComponents: [.hourAndMinute]
                    ).datePickerStyle(WheelDatePickerStyle())
                }
            }.animation(.spring())
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.