Skip to content

Commit

Permalink
fixed crash on time picker and date picker click
Browse files Browse the repository at this point in the history
  • Loading branch information
Kashif-E committed Dec 28, 2024
1 parent 490ca2a commit ae205f5
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import platform.UIKit.UIControlEventValueChanged
import platform.UIKit.UIDatePicker
import platform.UIKit.UIDatePickerMode
import platform.UIKit.UIDatePickerStyle
import platform.darwin.NSObject
import platform.objc.sel_registerName

@OptIn(
Expand All @@ -41,33 +42,25 @@ class DatePickerManager internal constructor(
) {
private val calendarModel = KotlinxDatetimeCalendarModel()

/**
* Pointer to the [dateSelection] method.
*/
@OptIn(ExperimentalForeignApi::class)
private val dateSelectionPointer get() = sel_registerName("dateSelection")

/**
* Dismisses the dialog.
*/
@OptIn(BetaInteropApi::class)
@ObjCAction
fun dateSelection() {
val components = NSCalendar.currentCalendar.components(
NSYearCalendarUnit or NSMonthCalendarUnit or NSDayCalendarUnit,
datePicker.date
)

val utcTimeMillis =
LocalDate(
year = components.year.toInt(),
monthNumber = components.month.toInt(),
dayOfMonth = components.day.toInt(),
private val datePickerDelegate = object : NSObject() {
@ObjCAction
fun onDateChanged(sender: UIDatePicker) {
val components = NSCalendar.currentCalendar.components(
NSYearCalendarUnit or NSMonthCalendarUnit or NSDayCalendarUnit,
sender.date
)
.atStartOfDayIn(TimeZone.UTC)
.toEpochMilliseconds()

onSelectionChanged(utcTimeMillis)
val utcTimeMillis =
LocalDate(
year = components.year.toInt(),
monthNumber = components.month.toInt(),
dayOfMonth = components.day.toInt(),
)
.atStartOfDayIn(TimeZone.UTC)
.toEpochMilliseconds()

onSelectionChanged(utcTimeMillis)
}
}

internal var aspectRatio by mutableFloatStateOf(0f)
Expand All @@ -92,23 +85,21 @@ class DatePickerManager internal constructor(
}

datePicker.setDate(date, animated = false)

datePicker.locale = getCalendarLocalDefault()
datePicker.timeZone = TimeZone.currentSystemDefault().toNSTimeZone()

datePicker.datePickerMode = UIDatePickerMode.UIDatePickerModeDate
datePicker.preferredDatePickerStyle = when (displayMode) {
UIKitDisplayMode.Picker ->
UIDatePickerStyle.UIDatePickerStyleInline

else ->
UIDatePickerStyle.UIDatePickerStyleWheels
UIKitDisplayMode.Picker -> UIDatePickerStyle.UIDatePickerStyleInline
else -> UIDatePickerStyle.UIDatePickerStyleWheels
}

// Add target using NSObject delegate
datePicker.addTarget(
target = this,
action = dateSelectionPointer,
target = datePickerDelegate,
action = sel_registerName("onDateChanged:"),
forControlEvents = UIControlEventValueChanged
)

datePicker.frame.useContents {
aspectRatio = this.size.width.toFloat() / this.size.height.toFloat()
}
Expand All @@ -127,5 +118,4 @@ class DatePickerManager internal constructor(
internal fun applyTheme(isDark: Boolean) {
datePicker.applyTheme(isDark)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import kotlinx.cinterop.ObjCAction
import kotlinx.cinterop.useContents
import platform.Foundation.*
import platform.UIKit.*
import platform.darwin.NSObject
import platform.objc.sel_registerName

@OptIn(ExperimentalForeignApi::class)
@InternalCalfApi
class TimePickerManager internal constructor(
private val datePicker: UIDatePicker,
initialMinute: Int,
Expand All @@ -20,47 +20,49 @@ class TimePickerManager internal constructor(
private val onHourChanged: (hour: Int) -> Unit,
private val onMinuteChanged: (minute: Int) -> Unit,
) {
/**
* Pointer to the [dateSelection] method.
*/
@OptIn(ExperimentalForeignApi::class)
private val dateSelectionPointer get() = sel_registerName("dateSelection")
private val datePickerDelegate = object : NSObject() {
@ObjCAction
fun onTimeChanged(sender: UIDatePicker) {
val components = NSCalendar.currentCalendar.components(
NSCalendarUnitHour or NSCalendarUnitMinute,
sender.date
)

/**
* Dismisses the dialog.
*/
@OptIn(BetaInteropApi::class)
@ObjCAction
fun dateSelection() {
val components = NSCalendar.currentCalendar.components(
NSCalendarUnitHour or NSCalendarUnitMinute,
datePicker.date
)

onHourChanged(components.hour.toInt())
onMinuteChanged(components.minute.toInt())
onHourChanged(components.hour.toInt())
onMinuteChanged(components.minute.toInt())
}
}

val datePickerWidth = mutableStateOf(0f)
val datePickerHeight = mutableStateOf(0f)

init {
val dateComponents = NSDateComponents()
dateComponents.minute = initialMinute.toLong()
dateComponents.hour = initialHour.toLong()
val dateComponents = NSDateComponents().apply {
minute = initialMinute.toLong()
hour = initialHour.toLong()
}

val date = NSCalendar.currentCalendar.dateFromComponents(dateComponents) ?: NSDate()
datePicker.date = date
datePicker.locale = NSLocale.currentLocale
datePicker.datePickerMode = UIDatePickerMode.UIDatePickerModeTime
datePicker.preferredDatePickerStyle = UIDatePickerStyle.UIDatePickerStyleWheels
datePicker.addTarget(
target = this,
action = dateSelectionPointer,
forControlEvents = UIControlEventValueChanged
)

datePicker.apply {
this.date = date
locale = NSLocale.currentLocale
datePickerMode = UIDatePickerMode.UIDatePickerModeTime
preferredDatePickerStyle = UIDatePickerStyle.UIDatePickerStyleWheels

// Add target using NSObject delegate
addTarget(
target = datePickerDelegate,
action = sel_registerName("onTimeChanged:"),
forControlEvents = UIControlEventValueChanged
)
}

datePicker.frame.useContents {
datePickerWidth.value = this.size.width.toFloat()
datePickerHeight.value = this.size.height.toFloat()
}
}


}

0 comments on commit ae205f5

Please sign in to comment.