如何从iOS ViewController通信到KotlinComposable

问题描述 投票:0回答:1
android

class CountdownViewModel : ViewModel() { private val totalTimeSeconds = 15 * 60 // 15 minutes in seconds private var remainingTime = totalTimeSeconds private val _time = MutableStateFlow(formatTime(remainingTime)) val time: StateFlow<String> = _time.asStateFlow() private val _progress = MutableStateFlow(1f) val progress: StateFlow<Float> = _progress.asStateFlow() private val _isRunning = MutableStateFlow(false) val isRunning: StateFlow<Boolean> = _isRunning.asStateFlow() fun startTimer() { if (isRunning.value) return _isRunning.value = true viewModelScope.launch { while (remainingTime > 0 && isRunning.value) { delay(1000) remainingTime-- _time.value = formatTime(remainingTime) _progress.value = remainingTime / totalTimeSeconds.toFloat() } _isRunning.value = false } } fun toggleTimer() { if (isRunning.value) stopTimer() else startTimer() } fun stopTimer() { _isRunning.value = false remainingTime = totalTimeSeconds _time.value = formatTime(remainingTime) _progress.value = 1f } private fun formatTime(seconds: Int): String { val minutes = seconds / 60 val secs = seconds % 60 return "%02d:%02d".format(minutes, secs) } }

ios

class CountdownViewModel: ObservableObject { private let totalTimeSeconds = 10 * 60 // 10 minutes in seconds private var remainingTime: Int private var timer: Timer? u/Published var time: String @Published var progress: Float @Published var isRunning: Bool init() { self.remainingTime = totalTimeSeconds self.time = CountdownViewModel.formatTime(totalTimeSeconds) self.progress = 1.0 self.isRunning = false } func startTimer() { if isRunning { return } isRunning = true timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in guard let self = self else { return } if self.remainingTime > 0 { self.remainingTime -= 1 self.time = CountdownViewModel.formatTime(self.remainingTime) self.progress = Float(self.remainingTime) / Float(self.totalTimeSeconds) } else { self.stopTimer() } } } func toggleTimer() { if isRunning { stopTimer() } else { startTimer() } } func stopTimer() { isRunning = false timer?.invalidate() timer = nil remainingTime = totalTimeSeconds time = CountdownViewModel.formatTime(remainingTime) progress = 1.0 } private static func formatTime(_ seconds: Int) -> String { let minutes = seconds / 60 let secs = seconds % 60 return String(format: "%02d:%02d", minutes, secs) } }

androidui

class MainActivity : ComponentActivity() { private val viewModel by viewModels<CountdownViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val progress by viewModel.progress.collectAsStateWithLifecycle(initialValue = 0f) val time by viewModel.time.collectAsStateWithLifecycle() val isRunning by viewModel.isRunning.collectAsStateWithLifecycle() App( onButtonClicked = { viewModel.toggleTimer() }, progress = progress, time = time, isRunning = isRunning ) } } }

IOSUI

MainViewController.kt

fun FullMainViewController( time: String, progress: Float, isRunning: Boolean, toggleTimer: () -> Unit ) = ComposeUIViewController { App( onButtonClicked = toggleTimer, progress = progress, time = time, isRunning = isRunning ) }

ContentView.swift

struct ComposeView: UIViewControllerRepresentable {
    @ObservedObject var viewModel: CountdownViewModel

    func makeUIViewController(context: Context) -> UIViewController {
        return MainViewControllerKt.FullMainViewController(
            time: viewModel.time,
            progress: viewModel.progress,
            isRunning: viewModel.isRunning,
            toggleTimer: { viewModel.toggleTimer() }
        )
    }

    func updateUIViewController(
            _ uiViewController: UIViewController,
            context: Context
    ) {}
}

struct ContentView: View {
    @StateObject private var viewModel = CountdownViewModel()
    
    var body: some View {
        ComposeView(
            viewModel: viewModel
        )
        .ignoresSafeArea(.keyboard) // Compose has own keyboard handler
    }
}

问题

Android应用程序运行良好,但我无法找到一种使iOS上的合并更新的方法。我的意思是,我可以在ComposeView中添加一个

.id(viewModel.time)
,以便每次都被调用,但性能看起来很糟糕。还有其他方法可以从iOS中更新合并吗?

notes
我知道你们中的一些人可能建议通过Kotlin共享相同的ViewModel,但我想避免这种情况。我正在考虑创建一个仅解决UI的解决方案,我希望能够将其作为UI库将其导入到Android和iOS中。
    

您必须将平台特定的代码放在数据层(

Https://developer.android.com/topic/architecture#recommend--app-arch-)。

数据层
makeUIViewController

UI层

expect fun createTimer(): Timer

uiviewcontroller android-jetpack-compose kotlin-multiplatform
1个回答
0
投票

val timer = createTimer()

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.