Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
551 views
in Technique[技术] by (71.8m points)

uinavigationcontroller - Navigation Bar Items not shown when UIKit > SwiftUI > UIKit

When pushing from a SwiftUI view to a UIKit, navigation bar items are not present or not added.

I have added one item in the storyboard and one item in code, neither show up.

This is possibly a bug in SwiftUI, but I feel like this is probably a pretty common case and perhaps I am missing something?

There is some overlap with this question: Navigation Bar Items after push from SwiftUI to UIKit although I am not sure if they are the same or not

Results

Gif of simulator

Inputs

Storyboard

  1. No code, Storyboard only
  2. No code, Storyboard only
class MyHostingController: UIHostingController<SwiftUIView> {
 
    required init?(coder aDecoder: NSCoder) {    
        super.init(coder: aDecoder, rootView: SwiftUIView())
    }
}
struct SwiftUIView: View {
    var body: some View {
        NavigationLink(
            destination: MyUIKitView(),
            label: {
                Text("Go to MyUIKitView")
            })
    }
}

Glue between 3 & 4

struct MyUIKitView: UIViewControllerRepresentable {
    typealias UIViewControllerType = MyUIKitViewController

    func makeUIViewController(context: Context) -> MyUIKitViewController {
        let sb = UIStoryboard(name: "Main", bundle: nil)
        let myVC = sb.instantiateViewController(identifier: "MyUIKitViewController") as! MyUIKitViewController
        return myVC
    }
    
    func updateUIViewController(_ uiViewController: MyUIKitViewController, context: Context) {
        print("??")
    }
}
class MyUIKitViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // ?? ADD NAV BUTTON HERE  
        navigationItem.rightBarButtonItems?.append(UIBarButtonItem(systemItem: .camera))
    }
}
  1. No code, Storyboard only
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

SwiftUI view used its own navigation controller and it ignores the UIKit navigation controller so the possible solution is to set your navigation bar to parent controller and set your navigation bar element by coding.

like this

class MyUIKitViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // ?? ADD NAV BUTTON HERE - must be in DispatchQueue
        DispatchQueue.main.async {
            self.parent?.navigationItem.title = "Your Title"
            self.parent?.navigationItem.rightBarButtonItems?.append(UIBarButtonItem(systemItem: .camera))
        }
    }
}

Another solution is to use self.navigationController?.navigationBar.topItem?. This is the exact same as above. It gives a topItem.

class MyUIKitViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // ?? ADD NAV BUTTON HERE - must be in DispatchQueue
        DispatchQueue.main.async {
            self.navigationController?.navigationBar.topItem?.title = "Your Title"
            self.navigationController?.navigationBar.topItem?.rightBarButtonItems?.append(UIBarButtonItem(systemItem: .camera))
        }
    }
}

I used DispatchQueue for when the view is initiated then the parent is not set at this time. (You can use also use viewWillAppear instead of DispatchQueue.main.async)

Edit

If you don't want to add elements programmatically and if you need to use the same element from the storyboard then you can use this approch.

class MyUIKitViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // ?? ADD NAV BUTTON HERE
        navigationItem.rightBarButtonItems?.append(UIBarButtonItem(systemItem: .camera))
        
        DispatchQueue.main.async { //<--Here
            self.navigationController?.navigationBar.topItem?.title = self.navigationItem.title
            self.navigationController?.navigationBar.topItem?.rightBarButtonItems = self.navigationItem.rightBarButtonItems
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...