Navigation bar title appears with delay in mixed UIKit and SwiftUI project - swiftui

I'm presenting a SwiftUI view from UIViewController.
let vc = UIHostingController(rootView: SwiftUIView())
navigationController?.pushViewController(vc, animated: true)
struct SwiftUIView: View {
var body: some View {
VStack {
}
.navigationBarTitle("Title")
}
}
The title appears only after the view has appeared. How to fix?

If you use UINavigationController then you need to set the title on the UIHostingController for it to appear instantly. Otherwise the navigation title will only appear after the SwiftUI view is rendered.
You can set the navigation title of any UIViewController using title
let vc = UIHostingController(rootView: SwiftUIView())
vc.title = "Title"
navigationController?.pushViewController(vc, animated: true)

Related

Unable to remove Navigation Bar when TabView is used inside the Navigation View - SwiftUI - iOS 15

SwiftUI View Hierarchy
Navigation View --> VStack --> Custom SearchView --> TabView
In the view, with the hierarchy mentioned above, I'm unable to remove navigation bar. It's visibility is successfully changed with the code mentioned shared below.
#available(iOS 15.0, *)
func iOS15UIBarSpecs(){
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.configureWithTransparentBackground()
navBarAppearance.backgroundColor = UIColor.red.withAlphaComponent(0.5)
navBarAppearance.shadowImage = UIImage()
navBarAppearance.shadowImage = nil
navBarAppearance.shadowColor = nil
UINavigationBar.appearance().standardAppearance = navBarAppearance
UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
}
The presence of this navigation bar is blocking tap gestures on any view coming behind it.
The same view was working fine in iOS 14 with the following line of code.
.navigationBarHidden(true)
Any help would be much appreciated. Thanks!

iOS 15 Status Bar Background Color in SwiftUI/UIKit Nav mix

We have an app which uses a mix of UIKit and SwiftUI. The nav hierarchy is:
UIKit Tab Bar > UIKit Table > SwiftUI View > UIKit View
as of iOS 15 the status bar is not taking on the color of the nav bar:
I'm trying to figure out if this is something I can fix.
Looking in Reveal it looks as tho the UIHostingView has a white bg:
Is it possible write code to change the bg color of the status bar in this setup?
This doesn't seem possible in a UIViewControllerRepresentable? And the hosted view is not taking up the whole screen, so changing that has no impact(?)
import SwiftUI
import PaddleCloud
struct PaddleMapView: UIViewControllerRepresentable {
typealias UIViewControllerType = MapViewController
var trip: Trip
var tripSpeeds: TripSpeeds
func makeUIViewController(context: Context) -> MapViewController {
let sb = UIStoryboard(name: "Map", bundle: nil)
let mapVC = sb.instantiateInitialViewController() as! MapViewController
mapVC.trip = trip
mapVC.tripSpeeds = tripSpeeds
return mapVC
}
}
NB: Changing the bg color in reveal does not change anything in the app.

Present a popover on button tap in Swift

I would like to make a popover from a button tap. but when I click on my button, my popover cover all my page. where is my problem?
#IBAction func buttonTap(sender: UIButton) {
// get a reference to the view controller for the popover
let popController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "popoverId")
// set the presentation style
popController.modalPresentationStyle = UIModalPresentationStyle.popover
// set up the popover presentation controller
popController.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.up
popController.popoverPresentationController?.delegate = self
popController.popoverPresentationController?.sourceView = sender // button
popController.popoverPresentationController?.sourceRect = sender.bounds
// present the popover
self.present(popController, animated: true, completion: nil)
}
I think you need to change the modalPresentaionStyle
popController.modalPresentationStyle = .overCurrentContext

Can't push from programmatically created UINavigationController

In a Swift 3 project using Xcode 8.3 and iOS 10.3, I get a navigation controller to push. The app runs with a navigation controller until I try to use it to push. All works until the last line which cause an app crash, fatal error: unexpectedly found nil while unwrapping an Optional value. I don't want to use the storyboard, the point of this question is how to accomplish this task without the storyboard.
App Delegate code
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: MainViewController())
}
View Controller:
import UIKit
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let navController = navigationController
let myProfileViewController = MyProfileViewController()
navController!.pushViewController(myProfileViewController, animated: true)
}
}
Move
let navController = navigationController
let myProfileViewController = MyProfileViewController()
navController!.pushViewController(myProfileViewController, animated: true)
from viewDidLoad to viewDidAppear.
In viewDidLoad there is no parent navigation controller set up and you should not start animations from there.
You can add navigation controller in storyboard,
in Storyboard click on MainViewController & from editor menu add navigation controller & push via navigation controller as below code.
let vc = self.storyboard?.instantiateViewController(withIdentifier: "MyProfileViewController") as! MyProfileViewController
self.navigationController?.pushViewController(vc, animated: true)
Make sure storyboard identifier is correct. & remove navigation controller code form AppDelegate class.
first give name to your navigation controller like this
then in your code initialise it like this
let nav = (UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "yourNavigation") as! UINavigationController);
nav.pushFrontViewController(MainViewController(), animated: true);
window?.rootViewController = nav

Swift 3 trying to create and use a UINavigationController programmatically

I'm working on an existing application which uses the storyboard but I want to continue development without using the storyboard at all, or nib files.
The existing left menu is a UITableView which is not the root controller and does not have a navigation controller associated with it. I have created a UINavigationController in the app delegate and want to use this navigation controller to push a new controller. I am able to present a view controller but I want to use push in order to conform with the current UIX.
In the following code nothing happens because navigationController? returns nil.
Here is my new code in the app delegate.
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var navController: UINavigationController?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
navController = UINavigationController()
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window!.rootViewController = navController
self.window!.backgroundColor = .red
self.window!.makeKeyAndVisible()
let menuViewController = SideMenuViewController()
menuViewController.navController = navController
Then in my side menu controller:
import UIKit
class SideMenuViewController: UIViewController {
var navController: UINavigationController?
.......
let myViewController = myViewController()
self.navigationController?.pushViewController(myViewController, animated: true )
From the UIViewController documentation:
var navigation​Controller:​ UINavigation​Controller?
The nearest
ancestor in the view controller hierarchy that is a navigation
controller.
Which means when you call self.navigationController in a view controller you get the (nearest) navigation controller that self is embedded in. Apparently your menu controller is not embedded in the navigation controller hierarchy. Using your app delegate's navController member is one way to make this work. Then you can say in your menu view controller:
func menuItemFooSelected()
{
let navController = (UIApplication.shared.delegate as! AppDelegate).navController
let myViewController = myViewController()
navController?.pushViewController(myViewController, animated: true)
}
Alternatively (and probably preferably), when you set up your initial structure in your app delegate, inject the navigation controller into the side menu controller:
class MenuViewController: UIViewController
{
var navController: UINavigationController?
...
func menuItemFooSelected()
{
let myViewController = myViewController()
self.navController?.pushViewController(myViewController, animated: true)
}
}
In application(_:didFinishLaunchingWithOptions:)
...
let menuViewController = MenuViewController(...)
menuViewController.navController = navController