example ios swift uidatepicker

ios - example - UIDatePicker comportamiento extraño con el calendario islámico



uidatepicker swift 4 example (1)

Nota: Bug reportado a Apple

Número de radar: 29265429 ( Link )

Estoy usando un UIDatePicker. Cuando le doy calendario gregoriano funciona bien. Los días empiezan del 1 al 31.

Sin embargo, cuando le doy el islamicUmmAlQura islámico, me da un comportamiento extraño. Los días comienzan de 1 a 30, pero hay un ''2'' por encima de 1 y por debajo de 30, de modo que los días son los siguientes 2,1,2,3,4 ... 30

He creado un nuevo proyecto vacío de iOS y he colocado el siguiente código en el método viewDidLoad :

let picker = UIDatePicker(frame: CGRect(x: 0, y: 30, width: 0, height: 0)) picker.datePickerMode = .date picker.date = Date() picker.calendar = Calendar(identifier: .islamicUmmAlQura) picker.autoresizingMask = UIViewAutoresizing.flexibleRightMargin picker.frame.size.width = 300 view.addSubview(picker)

Captura de pantalla:


No es tan difícil hacer su propio UIPicker que parece un UIDatePicker, pero debe tener cuidado porque el error está en NSCalendar y NSDatePicker .

Solo para dejar en claro que el ''2'' extra no se puede seleccionar, al igual que 30 no se puede seleccionar en un mes corto. NSDatePicker no oculta días o meses no válidos, pero los hace no seleccionables. Por lo tanto, en el calendario gregoriano, si selecciona febrero, seguirá viendo 29, 30 y 31, pero al seleccionarlos, el selector llegará a 28. El Selector de datos calcula cuántos meses y días debe mostrar llamando a maximumRangeOfUnit: en el calendario . En un calendario islámico, el máximo correcto es {1, 30}, pero NSCalendar devuelve {1,31} para maximumRangeOfUnit:NSCalendarUnitDay para todos los calendarios islámicos.

Así que hay dos errores. Una es que NSCalendar dice que puede haber 31 días en un Mes Islámico (lo que no creo que sea cierto), y el segundo problema es que NSDatePicker muestra el día 31 en lugar de 31.

Hacer tu propio NSDatePicker realmente no es tan difícil. La cantidad de elemento en cada componente es siempre la misma (solo asegúrese de establecer manualmente 30 para los días y no use el valor de NSCalendar). La parte difícil es decidir si una fecha no es válida y mostrar el elemento en gris y no dejar que el piquete se apoye en ella. Puede usar rangeOfUnit:InUnit:forDate para obtener la cantidad de días en un mes o la cantidad de meses en un año. Si un elemento no válido se selecciona, mueve el valor hacia abajo a la fecha válida más alta (es decir, si un usuario selecciona 30 en un mes con 29 días, selecciona 29).

Una vez que se selecciona una fila, puede convertir de día-mes-año a un NSDate con dateFromComponents en NSCalendar.