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

SwiftUI列表点击ShareView首次无内容,二次点击才显示的解决求助

问题原因

首次点击时,SwiftUI的状态更新是异步的:你先给TextExample赋值,再设置IsOpen = true,但SharingViewController的updateUIViewController方法会在TextExample的新值还没同步到视图上下文时就执行,导致闭包里捕获的TextExample还是初始空字符串。第二次点击时,状态更新已经完成,所以能拿到正确值。

解决方案

改用可选值来管理要分享的内容,确保只有当内容准备好后才触发分享视图的展示,同时优化SharingViewController的实现,避免闭包捕获旧状态的问题。

修改后的完整代码:

import SwiftUI

struct ContentView: View {
    let stringList = ["List 1","List 2","List 3","List 4","List 5"]
    @State private var sharedText: String? // 用可选值控制分享状态和内容

    var body: some View {
        List {
            ForEach(stringList, id: \.self) { string in
                Text(string)
                    .onTapGesture {
                        sharedText = string // 直接赋值,触发分享视图展示
                    }
            }
        }
        .background(
            SharingViewController(sharedText: $sharedText)
        )
    }
}

struct SharingViewController: UIViewControllerRepresentable {
    @Binding var sharedText: String?
    private var presentedVC: UIViewController? // 记录已展示的控制器,避免重复弹出

    func makeUIViewController(context: Context) -> UIViewController {
        UIViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        // 当有分享内容且未弹出控制器时,创建并展示
        if let text = sharedText, presentedVC == nil {
            let av = UIActivityViewController(activityItems: [text], applicationActivities: nil)
            av.completionWithItemsHandler = { _, _, _, _ in
                sharedText = nil // 分享完成后重置状态
                presentedVC = nil
            }
            uiViewController.present(av, animated: true)
            presentedVC = av
        }
        
        // 当sharedText被重置且控制器已展示时,关闭它(避免异常情况)
        if sharedText == nil, let vc = presentedVC, vc.presentingViewController != nil {
            vc.dismiss(animated: true)
            presentedVC = nil
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
关键改动说明
  • 用sharedText这个可选值同时管理是否展示分享视图和分享内容,确保只有内容存在时才触发弹出,从根源避免空内容问题。
  • 在SharingViewController中记录已展示的控制器实例,防止重复弹出,同时在分享完成后重置状态,保证下次点击正常工作。
  • 移除了原来的IsOpen状态变量,简化状态管理逻辑,减少异步更新带来的冲突。

内容的提问来源于stack exchange,提问作者user1591668

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:27:25