diff --git a/build-logic/convention/src/main/kotlin/io/github/kalinjul/convention/config/Multiplatform.kt b/build-logic/convention/src/main/kotlin/io/github/kalinjul/convention/config/Multiplatform.kt index e22e8a9..c90aba8 100644 --- a/build-logic/convention/src/main/kotlin/io/github/kalinjul/convention/config/Multiplatform.kt +++ b/build-logic/convention/src/main/kotlin/io/github/kalinjul/convention/config/Multiplatform.kt @@ -4,7 +4,6 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension fun KotlinMultiplatformExtension.configureIosTargets(baseName: String? = null) { listOf( - iosX64(), iosArm64(), iosSimulatorArm64() ).forEach { diff --git a/documentscanner-compose/src/iosMain/kotlin/io/github/kalinjul/easydocumentscan/DocumentScanner.ios.kt b/documentscanner-compose/src/iosMain/kotlin/io/github/kalinjul/easydocumentscan/DocumentScanner.ios.kt index f89f2eb..65e7893 100644 --- a/documentscanner-compose/src/iosMain/kotlin/io/github/kalinjul/easydocumentscan/DocumentScanner.ios.kt +++ b/documentscanner-compose/src/iosMain/kotlin/io/github/kalinjul/easydocumentscan/DocumentScanner.ios.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.uikit.LocalUIView import androidx.compose.ui.uikit.LocalUIViewController import platform.AVFoundation.AVErrorApplicationIsNotAuthorizedToUseDevice import platform.UIKit.UIButton @@ -19,7 +20,7 @@ actual fun rememberDocumentScanner( options: DocumentScannerOptions ): DocumentScanner { - val localViewController = LocalUIViewController.current + val localUiView = LocalUIView.current var delegate by remember() { mutableStateOf(null) } @@ -37,7 +38,7 @@ actual fun rememberDocumentScanner( onResult(Result.failure(exception)) }, onCancel = { - controller.dismissViewControllerAnimated(true) {} + controller.dismissModalViewControllerAnimated(false) }, onResult = { result -> controller.dismissViewControllerAnimated(true) {} @@ -53,7 +54,8 @@ actual fun rememberDocumentScanner( delegate = it // need to remember delegate else it is dereferenced } ) - localViewController.presentViewController(controller, animated = true) { + val viewController = localUiView.window?.rootViewController + viewController?.presentViewController(controller, animated = true) { if (options.ios.captureMode == DocumentCaptureMode.MANUAL) { controller.setManualMode() } diff --git a/gradle.properties b/gradle.properties index 8371870..ccf78d3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,6 @@ kotlin.code.style=official #MPP kotlin.mpp.stability.nowarn=true kotlin.mpp.enableCInteropCommonization=true -kotlin.mpp.androidSourceSetLayoutVersion=2 #Compose org.jetbrains.compose.experimental.uikit.enabled=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8f38438..6fbcc87 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,10 +8,10 @@ jvmTarget = "17" agp = "9.0.1" #https://github.com/JetBrains/compose-multiplatform -compose-multiplatform = "1.10.1" +compose-multiplatform = "1.11.1" material3 = "1.10.0-alpha05" #https://kotlinlang.org/docs/multiplatform-compatibility-guide.html -kotlin = "2.2.21" +kotlin = "2.4.0" # https://github.com/google/ksp ksp = "2.3.4" diff --git a/sample-app/shared/gradle.properties b/sample-app/shared/gradle.properties index 5769c5a..a3ff25c 100644 --- a/sample-app/shared/gradle.properties +++ b/sample-app/shared/gradle.properties @@ -7,7 +7,6 @@ android.useAndroidX=true #MPP kotlin.mpp.stability.nowarn=true #kotlin.mpp.enableCInteropCommonization=true -kotlin.mpp.androidSourceSetLayoutVersion=2 #Compose org.jetbrains.compose.experimental.uikit.enabled=true diff --git a/sample-app/shared/src/commonMain/kotlin/MainView.kt b/sample-app/shared/src/commonMain/kotlin/MainView.kt index 12e20ef..5e685a7 100644 --- a/sample-app/shared/src/commonMain/kotlin/MainView.kt +++ b/sample-app/shared/src/commonMain/kotlin/MainView.kt @@ -6,11 +6,15 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text +import androidx.compose.material3.rememberBottomSheetScaffoldState +import androidx.compose.material3.rememberModalBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -29,64 +33,87 @@ import io.github.kalinjul.easydocumentscan.KmpImage import io.github.kalinjul.easydocumentscan.rememberDocumentScanner import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterial3Api::class) @Composable fun MainView() { val snackbarHostState = remember() { SnackbarHostState() } + + var showBottomSheet by remember { mutableStateOf(false) } + if (showBottomSheet) { + + ModalBottomSheet( + onDismissRequest = { showBottomSheet = false } + ) { + var images by remember { mutableStateOf>(listOf()) } + var bitmapImages by remember { mutableStateOf>(listOf()) } + + LaunchedEffect(images) { + images.map { it.loadImage() }.also { bitmapImages = it } + } + + Column(modifier = Modifier) { + Text("Scanner Bottom sheet") + val scope = rememberCoroutineScope() + val scanner = rememberDocumentScanner( + onResult = { + if (it.isSuccess) { + images = it.getOrThrow() + scope.launch { + snackbarHostState.showSnackbar( + "${images.size} documents scanned", + duration = SnackbarDuration.Short + ) + } + } else { + println(it.exceptionOrNull()) + } + }, + options = DocumentScannerOptions( + DocumentScannerOptionsAndroid( + pageLimit = 3, + allowGalleryImport = true, + scannerMode = DocumentScannerModeAndroid.BASE + ), + DocumentScannerOptionsIos( + captureMode = DocumentCaptureMode.MANUAL + ) + ) + ) + Button(onClick = { + scanner.scan() + }) { + Text("Scan") + } + + LazyColumn { + items(bitmapImages) { + Image( + bitmap = it, + contentDescription = null + ) + } + } + } + } + } + Scaffold( snackbarHost = { SnackbarHost( hostState = snackbarHostState ) - } + }, ) { - var images by remember { mutableStateOf>(listOf()) } - var bitmapImages by remember { mutableStateOf>(listOf()) } - - LaunchedEffect(images) { - images.map { it.loadImage() }.also { bitmapImages = it } - } - Column(modifier = Modifier.padding(it)) { Text("Document Scanner demo") val scope = rememberCoroutineScope() - val scanner = rememberDocumentScanner( - onResult = { - if (it.isSuccess) { - images = it.getOrThrow() - scope.launch { - snackbarHostState.showSnackbar( - "${images.size} documents scanned", - duration = SnackbarDuration.Short - ) - } - } else { - println(it.exceptionOrNull()) - } - }, - options = DocumentScannerOptions( - DocumentScannerOptionsAndroid( - pageLimit = 3, - allowGalleryImport = true, - scannerMode = DocumentScannerModeAndroid.BASE - ), - DocumentScannerOptionsIos( - captureMode = DocumentCaptureMode.MANUAL - ) - ) - ) Button(onClick = { - scanner.scan() - }) { - Text("Scan") - } + scope.launch { + showBottomSheet = !showBottomSheet - LazyColumn { - items(bitmapImages) { - Image( - bitmap = it, - contentDescription = null - ) } + }) { + Text("Show Bottom sheet") } } }