How to achieve the auto-shrink SwiftUI Navigation Title with UIKit? - swift

I am trying to achieve the auto-shrink large nav title like the Navigation Title in SwiftUI, but no matter what my nav title always stay shrinked and never appear in large title mode. How do i fix this? (code below)
func setup() {
table.translatesAutoresizingMaskIntoConstraints = false
table.dataSource = self
table.delegate = self
table.register(UITableViewCell.self, forCellReuseIdentifier: "mycell")
table.separatorColor = .white
table.backgroundColor = .black
let appearance = UINavigationBarAppearance()
appearance.titleTextAttributes = [.foregroundColor: UIColor.black]
appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.black]
appearance.configureWithOpaqueBackground()
navigationItem.title = "Todo List"
navigationItem.scrollEdgeAppearance = appearance
navigationItem.standardAppearance = appearance
view.addSubview(table)
}

As well as providing a configuration for large titles, you need to instruct your navigationController to use large titles
navigationController.navigationBar.prefersLargeTitles = true
The default configuration for a view controller should be to automatically use large titles if that is the preferred choice. However you can set it explicitly per view controller:
navigationItem.largeTitleDisplayMode = .always // or .automatic or .never
If the nav controller has prefersLargeTitle = false then large titles will never be displayed whatever the largeTitleDisplayMode setting.

Related

Changing textfield font of UISearchBar also changes it's height

I am changing UISearchBar's UITextField font size:
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [.font: UIFont.systemFont(ofSize: 17)]
or
searchBar.searchTextField.font = .systemFont(ofSize: 17)
This is the same font size value as the default. But UISearchBar also changes its height. Looks like it's a little bit bigger than the default height value. How I can fix it?
Default UISearchBar height:
After font size change (pay attention that actual font size is the same as on screenshot above):
UPDATE:
I have a storyboard with UITabBarViewController in it. Then I have two UIViewControllers connected to UITabBarViewController. One of them is empty and another one contains UINavigationController with connected sample VIewController which is UITableViewController. Here is a sample code of test ViewController:
import UIKit
class ViewController: UITableViewController {
private lazy var searchController: UISearchController = {
let searchController = UISearchController(searchResultsController: nil)
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.autocapitalizationType = .none
searchController.searchBar.placeholder = "Search"
searchController.searchBar.barStyle = .black
searchController.searchBar.tintColor = .black
searchController.searchBar.keyboardAppearance = .light
return searchController
}()
override func viewDidLoad() {
super.viewDidLoad()
title = "TEST"
navigationItem.searchController = searchController
navigationItem.searchController?.searchBar.searchTextField.font = .systemFont(ofSize: 17)
definesPresentationContext = true
}
}

Swift: How to hide/move navigationTitle for small in-line navigation

I have a tableView that has a large navigation title of "My title". By default, when I scroll up, the large title turns into a small title. How do I go about hiding the small title during the small navigation bar but still show the large title when i scroll down? Is there a delegate i can use to notify me when navigation is transitioning for large title to small? Because my end result is to have my title be on the left bar bar button side when i scroll up.
Is there an easier to way move the title location to the left where left bar button would be?
My approach is create the left bar button with the same title as my navigation. I would hide it when my large navigation title is present then show it when large navigation title isnt. Meanwhile, I would hide the small navigation title when the small navigation bar is present. I hope this makes sense haha. Basically just trying to find a way to have my title on where the left bar button item should be.
Solution:
self.navigationItem.title = "hello"
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.titlePositionAdjustment = UIOffset(horizontal: -150, vertical: 0)
navBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navBarAppearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.title = "My Title"
let navBarAppearance = UINavigationBarAppearance()
navBarAppearance.titlePositionAdjustment = UIOffset(horizontal: -150, vertical: 0)
navBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navBarAppearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
navigationController?.navigationBar.standardAppearance = navBarAppearance
navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
navigationController?.navigationBar.prefersLargeTitles = true

UISearchBarSearchContainerView is black

Why it is black?
In viewDidLoad I set this code:
var searchController = UISearchController(searchResultsController: nil)
searchController.obscuresBackgroundDuringPresentation = false
navigationItem.searchController = searchController
definesPresentationContext = true
navigationItem.hidesSearchBarWhenScrolling = false
searchController.delegate = self
searchController.searchBar.delegate = self
Try to change the style of the search bar.
It will look like
searchController.searchBar.barTintColor = .blue
Here you can find how to change searchBar's appearance: https://developer.apple.com/documentation/uikit/uisearchbar/1624281-searchbarstyle
I had a similar problem when I set the app's "User Interface Style" to "Light" in info.plist. For some reason, the search bar doesn't appear to respect this setting and is rendering black when the device is in Dark Mode on iOS 13. I was able to force the search bar to render as white again by setting the search and navigation controllers' background colors.
searchController.searchBar.backgroundColor = .white
navigationController?.view.backgroundColor = .white

No navigation bar or any navigation bar attributes are showing up in view controller

I have a view controller that I want to have a navigation bar with a title and button to the right of the title. But for some reason the navigation bar is not showing up.
In the app delegate I added:
window?.rootViewController =
UINavigationController(rootViewController: MessagesController())
UITableViewCell.appearance().textLabel?.textColor = UIColor.white;
UITableViewCell.appearance().backgroundColor = UIColor.clear
UIApplication.shared.statusBarStyle = .lightContent
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]
UINavigationBar.appearance().barTintColor = UIColor(red:0.13, green:0.15, blue:0.18, alpha:1.0)
UIApplication.shared.isStatusBarHidden = false
In the viewDidLoad of the view controller I want to have the navigation bar this is my code:
override func viewDidLoad() {
super.viewDidLoad()
let dummyViewController = UIViewController()
dummyViewController.view.backgroundColor = .white
dummyViewController.navigationItem.title = "TEST"
navigationController?.navigationBar.tintColor = .white
Why is there no navigation bar and why can't I add a title with buttons to it? Any help is welcome Thank You.
I once ran into the same issue with a dark UINavigationBar. Try to add this line in your viewDidLoad:
self.navigationController?.navigationBar.barStyle = .black
This solved the issue for me. Let me know if it helps.

TVOS : Adjust the position of searchbar in UISearchViewController

I am developing an TVOS app. I use below code to implement search feature in UITabBarController. The issue when tabbar is displayed then search bar is covered by tabbar. See below screenshots. is it possible to move searchBar position down if tabbar gets displayed?
let searchViewController = VVSearchViewController()
let searchController = UISearchController(searchResultsController: searchViewController)
searchViewController.searchViewController = searchController
searchController.searchResultsUpdater = searchViewController
searchController.obscuresBackgroundDuringPresentation = true
let searchPlaceholderText = "Search"
searchController.searchBar.placeholder = searchPlaceholderText
searchController.searchBar.tintColor = UIColor.black
searchController.searchBar.barTintColor = UIColor.black
searchController.searchBar.searchBarStyle = .minimal
searchController.searchBar.keyboardAppearance = .dark
searchController.view.backgroundColor = UIColor.black
searchController.definesPresentationContext = true;
UISearchContainerViewController(searchController: searchController)
It is possible.
It took me a while but my idea was to add the search controller into a "container" controller with constraint at the top. Nothing will appear if you try adding UISearchController as child view controller into the container. UISearchContainerViewController doesn't work as well. But a navigation controller with UISearchContainerViewController as root works. Here is my code:
// Create the search controller and it's results controller
let resultsController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SearchResultsViewController") as! SearchResultsViewController
let searchController = UISearchController(searchResultsController: resultsController)
searchController.searchResultsUpdater = resultsController
// Customize it
UITextField.appearance(whenContainedInInstancesOf: [UISearchBar.self]).defaultTextAttributes = [.foregroundColor: UIColor.text]
searchController.searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchController.searchBar.tintColor = .text
searchController.searchBar.barTintColor = .text
searchController.searchBar.searchBarStyle = .minimal
searchController.searchBar.keyboardAppearance = .dark
// Embed it in UISearchContainerViewController
let searchContainerViewController = UISearchContainerViewController(searchController: searchController)
// Make UISearchContainerViewController root controller of a navigation controller
let navController = UINavigationController(rootViewController: searchContainerViewController)
// And a container to hold everything
let containerViewController = UIViewController()
// Do a standard child add of navController into containerViewController
navController.loadViewIfNeeded()
navController.viewWillAppear(false)
navController.willMove(toParent: containerViewController)
containerViewController.view.addSubview(navController.view)
navController.view.frame = containerViewController.view.bounds
// Add your constraints. In this case I just want the search bar to be 150 px down.
NSLayoutConstraint.activate([
navController.view.topAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.topAnchor, constant: 150),
navController.view.leftAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.leftAnchor),
navController.view.bottomAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.bottomAnchor),
navController.view.rightAnchor.constraint(equalTo: containerViewController.view.safeAreaLayoutGuide.rightAnchor)
]) containerViewController.addChild(navController)
containerViewController.addChild(navController)
navController.didMove(toParent: containerViewController)
navController.viewDidAppear(false)
// And from here use the containerViewController as normal to display a search into your app.
Note: Without passing the viewDidAppear on the navController this will not work.
Note 2: I tested this on tvOS 13 and 14 only.
You can find exactly the same case in the tab Search of the application "App Store".
This is because in tvOS the content of a viewController is not supposed to react to the visibility of the tab bar. The tab bar is presented instead on top of it, overlapping.
tvOS Human Interface GuideLines for Tab Bars:
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/tab-bars/