Trying to add buttons to my table view Navigation Bar - swift

I am trying to add a button to go back to a previous view controller. Since it is a table view Controller I have attempted to add a Navigation Controller hoping that I can put a button in there.
I have also tried doing it programmatically:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(handleCancel))
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(handleCancel))
fetchUser()
}
#objc func handleCancel(){
dismiss(animated: true, completion: nil)
}
Here is a picture of me attempting to set the navigation bar
link for image
I am not able to see the navigation item or the bar or anything. it is just the table showing up. anyone Knows how to actually get it to work?

I'm a little late but:
go to Main.storyboard -> in the top bar go to editor -> embed in -> navigation controller. do that to your viewController and than when u go to any other viewController from that ViewController you will be having that back button

Related

Navigation Bar Button Not Visible

This is my modified AppDelegate func
var window: UIWindow
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let button = UIBarButtonItem(title: "Logs", style: .plain, target: self, action: #selector(logButtonTapped))
window?.rootViewController?.navigationItem.rightBarButtonItem = button
return true
}
I also added Navigation Controller before my VC as below
Even if the title is visible, the right navigation button is not visible. How can I make the navigation button visible so that I can click on it?
Plus, I get this error on console
UINavigationBar decoded as unlocked for UINavigationController, or navigationBar delegate set up incorrectly. Inconsistent configuration may cause problems.
I am not sure if I understand what you are expecting very well. But I think you need to see the navBar button on the first page of your application. Isn't it?
So instead of doing this in the AppDelegate or SceneDelegate, you can add it directly to your viewController in the viewDidLoad() method.
It will be something like this:
override func viewDidLoad() {
super.viewDidLoad()
let button = UIBarButtonItem(title: "Logs", style: .plain, target: self, action: #selector(self.logButtonTapped))
navigationItem.rightBarButtonItem = button
}
If this is not what you need, please provide more info about this

Open swiftUI view from UIKit code for rightBarItem

This is code of UIKit File.I want to open view which is editButtonCustomizeView and written in swiftUI. How can I take action of this button which navigates to swiftUI
override func viewDidLoad() { super.viewDidLoad()
let editButton = UIBarButtonItem(image: editImage, style: .Plain,
target: self, action: editButtonCustomizeView())
}
Right now getting error is "Cannot convert value of type 'editButtonCustomizeView' to expected argument type 'Selector?' "
That is because the action expects a selector to point to what action is to be called when the button is tapped so you can't pass a view.
If you want to show a SwiftUI view when that button is tapped you have to first add a action to show the viewcontroller, then create the action to show the viewcontroller and lastly add you SwiftUI view in a viewcontroller so it can be used in UIKit.
Adding the action to the button:
let editButton = UIBarButtonItem(image: editImage, style: .Plain, target: self, action: #selector(showSwiftUIView))
Then the action to show the view:
#objc func showSwiftUIView(sender: UIControl) {
let vc = editButtonCustomizeVC()
present(vc, animated: true)
}
And lastly turn your view to a ViewController:
final class editButtonCustomizeVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let childView = UIHostingController(rootView: editButtonCustomizeView())
addChild(childView)
childView.view.frame = view.bounds
view.addSubview(childView.view)
childView.didMove(toParent: self)
}
}

UIButton is only responsive sometimes when pressing down [duplicate]

I have a UIBarButtonItem in the right side of my navigation that has an image of a gear and presents my settings view controller. I can get it to work properly when I create the button in setupNavigationBar(), but it doesn't work if I create the button as a property. I can't wrap my head around what would be different about these two scenarios. The button is present in both situations, but the functionality isn't.
This version doesn't work
class DecksController: UIViewController {
let settingsBarButton: UIBarButtonItem = {
let barButton = UIBarButtonItem(image: #imageLiteral(resourceName: "settings"), style: .plain, target: self, action: #selector(presentSettings))
return barButton
}()
override func viewDidLoad() {
super.viewDidLoad()
setupNavigationBar()
}
#objc func presentSettings() {
let settingsController = SettingsController()
self.navigationController?.pushViewController(settingsController, animated: true)
}
func setupNavigationBar() {
self.navigationItem.rightBarButtonItem = settingsBarButton
}
}
This version does work
class DecksController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupNavigationBar()
}
#objc func presentSettings() {
let settingsController = SettingsController()
self.navigationController?.pushViewController(settingsController, animated: true)
}
func setupNavigationBar() {
let settingsBarButton = UIBarButtonItem(image: #imageLiteral(resourceName: "settings"), style: .plain, target: self, action: #selector(presentSettings))
self.navigationItem.rightBarButtonItem = settingsBarButton
}
}
As you've discovered, it makes a big difference where this line occurs:
let barButton = UIBarButtonItem(image: #imageLiteral(resourceName: "settings"),
style: .plain, target: self, action: #selector(presentSettings))
The problem is the target:self part. When the bar button item is configured as part of an instance property initializer (your first example), the instance doesn't exist yet — it is what we are initializing. So self has no meaning, and the button ends up with no target. Therefore, tapping the button does nothing.
(Actually, to be quite technical, self is the class, but that's not a helpful thing to know.)
In your second example, that line is part of viewDidLoad, which runs considerably after the view controller instance has come into existence and has been initialized. viewDidLoad is an instance method, in fact. So self is the instance, as you expect.

How to set title of navigation item after open another view controller using with present modally - Swift

I have two view controllers in my application. Root view controller has some components and one of them is a button. That button provides to open another view controller using with present function. Second view controller(SelectTimeViewController) that opens when the button is tapped, was opened successfully. I am trying to set navigation title and items but I can not see them.
I did not use storyboard so root view controller is setting from AppDelegate.
let viewController = ViewController()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = UINavigationController(rootViewController: viewController)
window?.makeKeyAndVisible()
When tapped the button, "openVC" function is invoked.
#IBAction func openVC(_ sender: Any) {
self.navigationController?.present(SelectTimeViewController(), animated: true, completion: nil)
}
I am trying to set title and rightBarButtonItem in SelectTimeViewController's viewDidLoad function but I can not see both of them.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "close"), style: .plain, target: self, action: #selector(closeIt))
self.navigationItem.title = "Select Time"
}
In additional to this, I can see both title and right bar button item when change the "openVC" function like as bellow.
#IBAction func openVC(_ sender: Any) {
self.navigationController?.pushViewController(vc, animated: true)
}
You have to push the SelectTimeViewController instead of present
Or if you really want to present it, you should present another UINavigationController that has the rootViewController as SelectTimeViewController()

Search bar not aligned next to back button in navigation bar

I used a custom navigation controller class to remove the back button in my navigation bar, with the following:
class CustomNavigationController: UINavigationController, UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}
}
In one of my VCs, I also add a search controller to the navigation bar with the following:
private func configureSearchController() {
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.searchResultsUpdater = self
self.searchController.delegate = self
self.searchController.searchBar.delegate = self
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.dimsBackgroundDuringPresentation = true
self.navigationItem.titleView = searchController.searchBar
self.definesPresentationContext = true
}
However, it seems like the search bar is still being offset by some blank space where the title would be. I'd image the search bar should be aligned next to the back button, but there is the back button, space with blank title, then search bar.
How can I get the search bar aligned next to the back button instead of spaced because it seems there is some room for the blank title. Also, as a note, tapping on that blank space moves me back to the previous VC, although there is no actual title there.
EDIT:
View hierarchy, looks like the back button container view itself takes up a good amount of space
Try adding this in viewDidLoad
let backButton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
backButton.setBackButtonTitlePositionAdjustment(UIOffsetMake(-1000, -1000), for: .default)
navigationItem.backBarButtonItem = backButton