How to change the title registry using prefersLargeTitles? - swift

I know that it is possible to set font family, font size and color separately for «large» and «small» titles using prefersLargeTitles.
The question is: is there any options for navigation controller to show the «large title» in opened navigation panel with uppercase?
Now I use custom Navigation Controller:
class MyNavigationController: UINavigationController {
public var titleSaved: String?
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard let topItem = navigationBar.topItem else {
return
}
if navigationBar.frame.size.height > 60 {
topItem.title = topItem.title?.uppercased()
} else {
if let titleSaved = titleSaved {
topItem.title = titleSaved
} else {
topItem.title = topItem.title?.applyingTransform(StringTransform(rawValue: "Title"), reverse: false)
}
}
}
}
Set title from View Controlle:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
let title = "Sign In"
navigationItem.title = title
if let nc = navigationController as? MyNavigationController {
nc.titleSaved = title
}
}
}
this solution works, but when you switch from "large" title to "small" title and backwards it twitches and it looks pretty buggy

You can have an uppercased title for «large title» and capitalized title for «small title» using Small caps fonts
Change titleTextAttributes with other font and change largeTitleTextAttributes with caps font
class ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Sign In"
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.red]
self.navigationController?.navigationBar.largeTitleTextAttributes = [.foregroundColor: UIColor.red,
.font:UIFont(name: "Panton-LightCaps", size: 30)!]
}
}
Or You can customize your font. I've created a new style font using OpenSans in http://www.glyphrstudio.com/online/
You can download it here
self.title = "Sign In"
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.titleTextAttributes = [.font:UIFont(name: "OpenSans-Regular", size: 30)!]
self.navigationController?.navigationBar.largeTitleTextAttributes = [.font:UIFont(name: "MyFontRegular", size: 30)!]

you can try like this:
navigationController?.navigationBar.prefersLargeTitles = true
let NavigationTitle = "Sign in"
navigationController?.navigationBar.topItem?.title = NavigationTitle.uppercased()

You just try to set a navigationbar title as uppercased. and set pregfersLargeTitles as true
self.navigationController?.navigationBar.prefersLargeTitles = true
self.title = "title".uppercased()
Check this:

Related

UINavigationBar LargeTitle , searchbar didn't work

enter image description here
enter image description here
I want to make it like the picture below, but it comes out like the picture above.
Here is My Code.
lazy var button = UIDropDownButton().then {
$0.setAction().subscribe(onNext: {
switch $0 {
case .popularity: break
// 인기순 정렬 코드
case .suggestion: break
// 추천순 정렬 코드
case .lowestPrice: break
// 최저가순 정렬 코드
}
})
.disposed(by: disposeBag)
}
lazy var barButtonItem = UIBarButtonItem(customView: button)
override func viewDidLoad() {
super.viewDidLoad()
setNavigationBar()
}
override func viewWillAppear(_ animated: Bool) {
setNavigationBar()
}
private func setNavigationBar() {
setLargeTitleNavigationBar(title: "제품")
self.navigationItem.rightBarButtonItem = barButtonItem
let searchController = UISearchController(searchResultsController: nil)
self.navigationItem.searchController = searchController
}
setLargeTitleNavigationBar Method is here.
extension UIViewController {
func setLargeTitleNavigationBar(title: String) {
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.setBackButon()
self.navigationController?.navigationBar.backgroundColor = nil
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
self.navigationItem.title = title
}
I don't know how to solve this problem.
I like Snapkit, but I can read storyboard.
use this
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always

Changing the back button of UINavigaitonBar with MVVM+C

I am using MVVM+C pattern to build my app. Currently I am facing a problem with changing the native back button title and image of navigation bar to the custom image without the title. I've tried a lots of solutions what I was able to find, but nothing set the different title or even an image. I've ended up with this code in AppDelegate.swift:
let navigationController: UINavigationController = .init()
if #available(iOS 13.0, *) {
let appearence = UINavigationBarAppearance()
appearence.configureWithOpaqueBackground()
appearence.backgroundColor = .backgroundColor
appearence.shadowColor = nil
appearence.shadowImage = nil
navigationController.navigationBar.standardAppearance = appearence
navigationController.navigationBar.scrollEdgeAppearance = navigationController.navigationBar.standardAppearance
} else {
navigationController.navigationBar.isTranslucent = false
navigationController.navigationBar.barTintColor = .backgroundColor
navigationController.navigationBar.shadowImage = nil
navigationController.navigationBar.shadowColor = nil
}
// This code is not working at all, always get "Back" as a default with default image =====
let backButtonBackgroundImage = UIImage(named: "backButton")
navigationController.navigationBar.backIndicatorImage = backButtonBackgroundImage
navigationController.navigationBar.backIndicatorTransitionMaskImage = backButtonBackgroundImage
let backBarButtton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
navigationController.navigationItem.backBarButtonItem = backBarButtton
// =========
navigationController.navigationBar.tintColor = .primary
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
Also, I've followed the official documentation but without any success. As default I've set the navigation bar as hidden (because is not needed for multiple times) and I am showing it in ViewWillAppear and hiding in ViewWillDisappear methods.
Is there someone who has an idea of what's going on? Thanks!
The result of this code:
Expected result:
This is what I get with the new code:
SOLUTION:
After using code from Scott I was able to change the image and look of the navigation bar but I lost the ability to swipe back. After adding this code to the UINavigationBar extension I was able to get it back:
extension UINavigationController: UIGestureRecognizerDelegate {
#objc func goBack(sender: Any?) {
self.popViewController(animated: true)
}
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
Below is some Playground code that shows a UINavigationController with a custom back button that is an image.
Note that what it does is hides the system provided back button, then substitutes another button that still performs the "back" action but on a custom UINavigationController.
There may be a more efficient way to duplicate the functionality of "back" that doesn't involve a custom class and a custom target-action setup, but I couldn't find one quickly so finding that solution can be left as an exercise for the reader.
import UIKit
import SwiftUI
import PlaygroundSupport
NSSetUncaughtExceptionHandler { error in
debugPrint(error)
}
class MyNavController : UINavigationController {
#objc func goBack(sender: Any?) {
self.popViewController(animated: true)
}
}
let navDestination1 = UIViewController()
navDestination1.navigationItem.title = "Destination 1"
let navigationController = MyNavController(rootViewController: navDestination1)
if #available(iOS 13.0, *) {
let appearence = UINavigationBarAppearance()
appearence.configureWithOpaqueBackground()
appearence.backgroundColor = .purple
appearence.shadowColor = nil
appearence.shadowImage = nil
navigationController.navigationBar.standardAppearance = appearence
navigationController.navigationBar.scrollEdgeAppearance = navigationController.navigationBar.standardAppearance
} else {
navigationController.navigationBar.isTranslucent = false
navigationController.navigationBar.barTintColor = .purple
navigationController.navigationBar.shadowImage = nil
}
let navDestination2 = UITableViewController()
navDestination2.navigationItem.title = "Destination 2"
navDestination2.navigationItem.hidesBackButton = true
navDestination2.navigationItem.leftBarButtonItem = UIBarButtonItem(
image: UIImage(systemName: "multiply.circle.fill"),
style: UIBarButtonItem.Style.done,
target: navigationController,
action: #selector(MyNavController.goBack))
navigationController.pushViewController(navDestination2, animated: true)
navigationController.view.bounds = CGRect(x: 0,y: 0,width: 320,height: 480)
PlaygroundSupport.PlaygroundPage.current.liveView = navigationController

New default search bar focus text color added with Xcode 8.1 update, how to change it?

Question:
How do I set the "focused" state of a UISearchBar text color from the default white, to black?
I created the search bar programmatically, see end of post for that code.
Description:
Previously I was using this extension to set the search bar color:
public extension UISearchBar {
public func setTextColor(color: UIColor) {
let svs = subviews.flatMap { $0.subviews }
guard let tf = (svs.filter { $0 is UITextField }).first as? UITextField else { return }
tf.textColor = color
}
}
Which worked great and is still working. However, search bars seem to be "focusable" in a sense. If they are focused, then the text color switches to white (which is the same as the search bar background color) making the text invisible.
Under my search bar I have a table view, where I populate it with data regarding what the person was searching.
When I focus any of the table cells, the UISearchBar text color goes to the black I had originally specified.
Programmatically created SearchBar
Called in AppDelegate.swift
func configueSearchController() -> UIViewController {
let storyboard = UIStoryboard(name: "Search", bundle: nil)
guard let searchResultsController = storyboard.instantiateViewController(withIdentifier: SearchViewController.storyboardIdentifier) as? SearchViewController else {
fatalError("Unable to instatiate a SearchResultViewController from the storyboard.")
}
/*
Create a UISearchController, passing the `searchResultsController` to
use to display search results.
*/
let searchController = UISearchController(searchResultsController: searchResultsController)
searchController.searchResultsUpdater = searchResultsController
searchController.searchBar.placeholder = NSLocalizedString("Enter keyword (e.g. Gastric Bypass)", comment: "")
searchController.view.backgroundColor = Constants.Color.backgroundcolor
searchController.searchBar.keyboardAppearance = UIKeyboardAppearance.dark
searchController.searchBar.tintColor = Constants.Color.backgroundcolor
searchController.searchBar.backgroundColor = Constants.Color.backgroundColorSearch
searchController.searchBar.setTextColor(color: .black)
searchController.hidesNavigationBarDuringPresentation = false
searchController.obscuresBackgroundDuringPresentation = true
searchController.searchBar.searchBarStyle = .minimal
searchController.searchBar.sizeToFit()
//searchResultsController.tableView.tableHeaderView = searchController.searchBar
// Contain the `UISearchController` in a `UISearchContainerViewController`.
let searchContainer: UISearchContainerViewController = UISearchContainerViewController(searchController: searchController)
// Finally contain the `UISearchContainerViewController` in a `UINavigationController`.
let searchNavigationController = UINavigationController(rootViewController: searchContainer)
searchNavigationController.navigationBar.isTranslucent = true
searchNavigationController.navigationBar.tintColor = Constants.Color.backgroundcolor
searchNavigationController.tabBarItem.title = "Search"
return searchNavigationController
}

How to change text of navigation bar (UISearchController)?

I have created a navigation bar with UISearchController.
Below is my code:
#IBAction func showSearchController(sender: AnyObject) {
let searchController = UISearchController(searchResultsController: searchResultController)
searchController.searchBar.delegate = self
/*
searchController.searchBar.placeholder = "hhhhhhhhhhh"
searchController.navigationItem.title = "hhhhhhhhhhh"
searchController.navigationController?.navigationBar.topItem?.title = "hhhhhhhh" -->i try these codes for to change*/
self.presentViewController(searchController, animated: true, completion: nil)
}
But I can't change the text.
var searchTextField = searchController.searchBar.valueForKey("_searchField") as! UITextField
searchTextField.placeholder = "Your Custom Text"
Use this to change your place holder text

Change title and message font of alert using UIAlertController in Swift

I am trying to change the title and message font for an alert shown using UIAlertController
I am trying to do using an NSAttributedStirng, but it gives compiler error that a NSAttributed string cannot be taken instead of Stirng
I tried something similar to this
var title_attrs = [NSFontAttributeName : CustomFonts.HELVETICA_NEUE_MEDIUM_16]
var msg_attrs = [NSFontAttributeName : CustomFonts.HELVETICA_NEUE_REGULAR_14]
var title = NSMutableAttributedString(string:"Done", attributes:title_attrs)
var msg = NSMutableAttributedString(string:"The job is done ", attributes:msg_attrs)
let alertController = UIAlertController(title: title, message: title , preferredStyle: UIAlertControllerStyle.Alert)
Can someone guide me how can I achieve this?
Swift 3 Version:
extension UIAlertController {
func changeFont(view: UIView, font:UIFont) {
for item in view.subviews {
if item.isKind(of: UICollectionView.self) {
let col = item as! UICollectionView
for row in col.subviews{
changeFont(view: row, font: font)
}
}
if item.isKind(of: UILabel.self) {
let label = item as! UILabel
label.font = font
}else {
changeFont(view: item, font: font)
}
}
}
open override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let font = YOUR_FONT
changeFont(view: self.view, font: font! )
}
}
I think Apple removed the attributedTitle and -message from the API. It was never part of the public API so it might be that Apple will not allow your app in the app store if you used it.
You should use the UIAlertController as is. If you want to customise it a bit see this NSHipster post. If you want more control, create a custom View to display.
let myString = "Alert Title"
var myMutableString = NSMutableAttributedString()
myMutableString = NSMutableAttributedString(string: myString as String, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!])
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: NSRange(location:0,length:myString.characters.count))
alertController.setValue(myMutableString, forKey: "attributedTitle")
alertController.setValue(myMutableString, forKey: "attributedMessage")
extension UIAlertController {
func changeFont(view:UIView,font:UIFont) {
for item in view.subviews {
if item.isKindOfClass(UICollectionView) {
let col = item as! UICollectionView
for row in col.subviews{
changeFont(row, font: font)
}
}
if item.isKindOfClass(UILabel) {
let label = item as! UILabel
label.font = font
}else {
changeFont(item, font: font)
}
}
}
public override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let font = UIFont(name: YourFontName, size: YourFontSize)
changeFont(self.view, font: font! )
}
}