You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SwiftUI中ChatView导航栏标题不显示问题排查与解决

解决SwiftUI导航栏标题不显示的问题

看起来你遇到的核心问题是导航栏被全局隐藏,加上标题设置的层级不对,导致进入ChatView后看不到好友名称。我来帮你一步步排查修复:

问题根源分析

  1. 导航栏被全局隐藏:你在Cells页面的List上添加了.navigationBarHidden(true),这会让整个NavigationView的导航栏处于隐藏状态,后续跳转的页面自然也无法显示导航栏和标题。
  2. 标题修饰符位置错误:你把.navigationBarTitle加在了NavigationLink上,这个修饰符应该作用在导航栈的视图层级上,而非单个链接。
  3. 无效的SwiftUI修饰符调用:在ChatViewmakeUIViewController里调用self.navigationBarTitle(...)是错误的,这个方法是SwiftUI View的修饰符,不能直接在UIViewControllerRepresentable结构体内部调用。

修复步骤

1. 修复Cells页面的导航栏设置

首先移除隐藏导航栏的代码,并把列表页面的标题放在正确的层级:

var body : some View{
    NavigationView {
        List(getPairsUser()){i in
            NavigationLink(destination: ChatView(friend:i)
                // 在这里给ChatView设置导航标题
                .navigationTitle(i.name)
                .navigationBarTitleDisplayMode(.inline)
            ){
                cellView(user : i)
            }
        }
        // 把列表页面的标题放在List层级上
        .navigationBarTitle(Text("Friends List"), displayMode: .inline)
        // 移除这行:.navigationBarHidden(true)
    }
    .frame(minWidth: UIScreen.main.bounds.width, idealWidth: UIScreen.main.bounds.width, maxWidth: UIScreen.main.bounds.width, maxHeight: .infinity)
    .clipShape(Rounded())
}

2. 清理ChatView中的无效代码

去掉ChatView里那些无效的标题设置代码,保持逻辑简洁:

struct ChatView: UIViewControllerRepresentable {
    @EnvironmentObject var obser:Observer
    var db = Firestore.firestore()
    var friend:User
    var messageRef:CollectionReference!
    var pairRef:CollectionReference!
    
    init(friend:User){
        self.friend = friend
    }
    
    func updateUIViewController(_ uiViewController: ChatViewController, context: Context) {
        if(uiViewController.left){
            if(!self.obser.messageListenerFlag[friend.pairUid]!){
                self.obser.messageListenerFlag[friend.pairUid] = true
                if( uiViewController.lastMessageDate != nil){
                    self.obser.pairLastMessages[friend.pairUid] = uiViewController.lastMessage
                    self.obser.pairLastMessagesDate[friend.pairUid] = uiViewController.lastMessageDate
                }
            }
        }
    }
    
    func makeUIViewController(context: Context) -> ChatViewController {
        let chatViewController = ChatViewController()
        // 如果你需要在UIKit层面控制标题,可以保留这行,但SwiftUI的设置会优先生效
        // chatViewController.navigationItem.title = self.friend.name
        chatViewController.senderId = self.obser.__THIS__.Uid
        chatViewController.senderDisplayName = self.obser.__THIS__.Name
        chatViewController.friend = self.friend
        chatViewController.messageRef = self.db.collection("pairs").document(self.friend.pairUid).collection("messages")
        chatViewController.pairRef = self.db.collection("pairs").document(self.friend.pairUid).collection("typingIndicator")
        chatViewController.__THIS__ = self.obser.__THIS__
        
        // 优化图片加载逻辑(避免同步网络请求阻塞线程)
        if let _url = URL(string: self.friend.image) {
            URLSession.shared.dataTask(with: _url) { data, _, _ in
                if let data = data {
                    DispatchQueue.main.async {
                        chatViewController.friendImage = UIImage(data: data)
                    }
                }
            }.resume()
        }
        
        self.obser.messageListenerFlag[friend.pairUid] = false
        self.obser.unreadMessageCount[friend.pairUid]? = 0
        return chatViewController
    }
    
    typealias UIViewControllerType = ChatViewController
}

额外优化提示

  • 我还帮你优化了图片加载逻辑,原来的try? Data(contentsOf: _url)是同步网络请求,会阻塞主线程导致界面卡顿,换成了异步的URLSession请求。
  • 如果你需要自定义导航栏的橙色样式,可以在NavigationView上添加.navigationBarColor(.orange)这类自定义修饰符(需要扩展UINavigationBar实现)。

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

火山引擎 最新活动