You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose Multiplatform多Activity实现:iOS端actual类编写疑问

Compose Multiplatform iOS端页面跳转与参数传递解决方案

首先明确:iOS端的actual实现用Kotlin编写即可,不需要Swift,因为共享层的expect定义属于Kotlin代码,对应的actual实现必须是Kotlin/Native代码(可直接调用iOS的UIKit API)。

你的思路里用CustomActivity模拟Android的Activity并不适配iOS的导航模型——iOS没有Activity概念,页面导航依赖UINavigationController管理的视图控制器栈。正确的做法是抽象导航服务,通过expect/actual实现两端各自的导航逻辑:

1. 共享层定义导航服务接口

在共享模块中创建expect类,抽象导航行为和参数传递:

expect class NavigationService {
    // 示例:跳转到详情页并传递字符串参数
    fun navigateToDetail(param: String)
}

2. Android端actual实现

利用Android原生的Intent和Activity完成跳转:

actual class NavigationService actual constructor(private val context: Context) {
    actual fun navigateToDetail(param: String) {
        val intent = Intent(context, DetailActivity::class.java).apply {
            putExtra("DETAIL_PARAM", param)
        }
        context.startActivity(intent)
    }
}

// 对应的DetailActivity
class DetailActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val param = intent.getStringExtra("DETAIL_PARAM") ?: ""
        setContent {
            DetailScreen(param = param)
        }
    }
}

3. iOS端actual实现

通过Kotlin/Native调用UIKit的UINavigationController,push包含目标Composable的UIHostingController:
首先在iOS端的Swift代码中,持有全局可访问的导航控制器(比如在AppDelegate中):

import UIKit
import ComposeUI

class AppDelegate: UIResponder, UIApplicationDelegate {
    static var sharedNavController: UINavigationController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 初始化主页面的Compose视图
        let mainView = MainScreen(navigationService: NavigationService())
        let hostingController = UIHostingController(rootView: mainView)
        // 创建导航控制器并设置为根
        let navController = UINavigationController(rootViewController: hostingController)
        AppDelegate.sharedNavController = navController
        
        // 设置Window(省略常规配置)
        let window = UIWindow(frame: UIScreen.main.bounds)
        window.rootViewController = navController
        window.makeKeyAndVisible()
        return true
    }
}

然后在iOS模块的Kotlin代码中实现actual类:

import platform.UIKit.UINavigationController
import platform.UIKit.UIHostingController

actual class NavigationService actual constructor() {
    // 获取iOS端的导航控制器引用
    private val navController = AppDelegate.sharedNavController

    actual fun navigateToDetail(param: String) {
        // 创建包含目标Composable的UIHostingController
        val detailView = DetailScreen(param = param)
        val hostingController = UIHostingController(rootView = detailView)
        // 执行跳转
        navController?.pushViewController(hostingController, animated = true)
    }
}

4. 共享层Composable中使用导航服务

在按钮点击事件中直接调用导航服务的方法:

@Composable
fun MainScreen(navigationService: NavigationService) {
    Button(onClick = {
        navigationService.navigateToDetail("传递的参数内容")
    }) {
        Text("跳转到详情页")
    }
}

// 目标详情页Composable
@Composable
fun DetailScreen(param: String) {
    Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
        Text("收到的参数:$param")
    }
}

关键说明

  • iOS端不需要编写Swift导航逻辑,Kotlin/Native可直接调用UIKit API完成视图控制器跳转。
  • 参数传递无需依赖iOS原生机制,直接在共享层的Composable和导航方法中传递Kotlin对象即可,更简洁。
  • 避免模拟Android的Activity概念,适配iOS导航模型才能让跨平台代码更合理。

内容的提问来源于stack exchange,提问作者Jakub Mroziński

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:22:43