Search code examples
iosswiftiphoneswiftuidatepicker

How to increase tappable area of DatePicker in SwiftUI


I am creating a custom date picker using swiftUI with a placeHolder text.However, datepicker is popping only if I tap on text .I want it to pop whenever I tap on entire white background

enter image description here

I tried using .compositeGroup, .scaleEffect, but nothing seems to be working.the tap area is not increasing.I am attaching my code. I want the datepicker to popup whenever I tap on the entire white background as in attached image

ZStack {
    Rectangle()
        .foregroundColor(.whiteGeneric)
        .frame(height: 50)
        .cornerRadius(25)

    HStack(spacing: 10) {
        Image(.calendar)
            .resizable()
            .frame(width: 21, height: 21)
            .padding(.leading, 25)

        DatePicker("", selection: $selectedDate, displayedComponents: .date)
            .labelsHidden()
            .overlay {
                ZStack {
                    Color.white

                    Text(selectedDate == Calendar.current.date(from: DateComponents(year: 2020, month: 1, day: 1))! ? "Date of Incident" : getdateFormatter(with: "MM/dd/yyyy").string(from: selectedDate))
                        .font(AppFont.robotoRegular.size(15))
                        .foregroundStyle(.primaryText)
                        .lineLimit(1)
                        .minimumScaleFactor(0.5)
                }
                .allowsHitTesting(false)
            }

        Spacer()
    }
}

Solution

  • What is needed is a way to increase the footprint of the default date picker.

    • I found that .scaleEffect does in fact work. You only need to scale in the horizontal plane, not the vertical plane. This prevents the area above and below the styled field from becoming tappable too.

    • Fortunately, the scale effect doesn't seem to impact the popup version (at least, when testing on an iPhone 16 simulator with iOS 18.0).

    • I would suggest using .background to put the date picker behind the ZStack. Then apply a clip shape to the ZStack. This way, the date picker does not impact the size of the ZStack and remains completely hidden behind the other content.

    • The modifier .allowsHitTesting(false) needs to be applied to the complete ZStack, before adding the picker in the background.

    ZStack(alignment: .leading) {
        Color.whiteGeneric
    
        HStack(spacing: 10) {
            Image(.calendar)
                .resizable()
                .frame(width: 21, height: 21)
    
            Text(selectedDate == Calendar.current.date(from: DateComponents(year: 2020, month: 1, day: 1))! ? "Date of Incident" : getdateFormatter(with: "MM/dd/yyyy").string(from: selectedDate))
                .font(AppFont.robotoRegular.size(15))
                .foregroundStyle(.primaryText)
                .lineLimit(1)
                .minimumScaleFactor(0.5)
        }
        .padding(.leading, 25)
    }
    .frame(height: 50)
    .allowsHitTesting(false)
    .background {
        DatePicker("", selection: $selectedDate, displayedComponents: .date)
            .labelsHidden()
            .scaleEffect(x: 5, y: 1)
    }
    .clipShape(Capsule())
    

    Animation