iOS 13 SearchController Back Button Color - swift

I have a strange visual bug in my app that only applies to iOS 13 running from an Xcode 11 build. I have a table view embedded in a Navigation Controller with the default tint color set to my app's primary orange color. On iOS12, when you cancel the search action, you are presented with a back button that follows the global nav controller tint of primary orange. This is the expected behavior. Image shown below:
However, this same code in iOS13 produces a system default BLUE back arrow, as shown below:
I have tried EVERYTHING to try and override that blue back button, including creating a custom Bar Button Item with a custom action, but that is way too messy and I want to just simply override the tint color. I've tried the obvious searchController.searchBar.tintColor = UIColor(named:"Primary") where searchController is my UISearchController, and I have tried to override the self.navigationController tint color. I've tried accessing the SearchBar natively, like this: UISearchBar.appearance().tintColor = UIColor(named:"Primary"), but still no luck. I've tried everything else I can think of in the IB, but I can not figure out how to reach this back button's tint color. Can anybody help?

The only way I found so far to get this fix on iOS13.1 is to iterate through the subviews in the navigation bar and manually modified the tintColor.
None of the new UINavigationBarAppearance methods looks like they fix the problem. If you modified the backButtonAppearance in UINavigationBarAppearance I have been able to fix the title in back button but I haven't found a way to fix the image (<).

try this
override func viewWillAppear(_ animated: Bool) {
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
self.navigationItem.backBarButtonItem?.tintColor = .blue
}

In iOS 13 there are few new appearance types for the navigation bar. When you want to customize navigation bar which associated with a large title or any kind of scroll view just setup appearance parameters for .scrollEdgeAppearance
if #available(iOS 13.0, *) {
let standartAppearence = UINavigationBarAppearance()
standartAppearence.configureWithDefaultBackground()
// Your configuration
UINavigationBar.appearance().scrollEdgeAppearance = standartAppearence
}

It turns out that this was an XCode/Swift bug only affecting iOS 13.1. It should not be something that you have to account for in code, since only a very small portion of the user base is still on 13.1.

Related

Change the title color of a navigation item in Xcode 11.4

I cannot change the title color of a navigation item. It is an old project with support for iOS 10.0+.
Setting the title:
navigationItem.title = "My Title"
Someone changed the property titleColor (in Title Text Attributes) of a navigation bar in a storyboard. And now it doesn't work. It is strange because it works in Xcode 11.3.1, but doesn't work in Xcode 11.4.
Attempts to change the title color:
navigationController?.navigationBar.titleTextAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.mainGold ] (also I
tried different keys here)
navigationController?.navigationBar.tintColor =
UIColor.mainGold (also tried barTintColor :D)
I tried to add it in viewDidLoad, viewDidAppear, etc
I tried it with UINavigationBar.appeareance() in AppDelegate. And it works in an empty project. It also works for the navigation item title in my first view controller.
There are a lot of screens in my project, and something blocks changing the title color. The title color of a navigation item is always white (for dark theme) or black (for light theme).
It does confuse me.
Screenshot of the view hierarchy. UILabel LUXURIES is the title of a navigation item:
I updated Xcode to version 11.4.1 (11E503a) and it fixed the issue.
I think it was a strange Xcode bug. I tried to reproduce it in an empty project, but I couldn't.

UITableViewCells visible behind title when scrolling up in swift

This is probably a simple fix, but I haven't been able to figure out what's going on.
I have a UITableView that looks like this:
When I scroll up, however, the cells are visible behind the title, like so:
I've tried changing the navigation bar to opaque in appDelegate:
UINavigationBar.appearance().isOpaque = true
I have also tried editing the top insets on the UITableView without success. Any thoughts?
If anyone else has the same problem, I just had to set the UINavigationBar tint color like so, and make it non-translucent:
UINavigationBar.appearance().barTintColor = colorDict[currentClerkship]
UINavigationBar.appearance().isTranslucent = false

Prevent VoiceOver revealing views that are beneath a larger transparent view

Summary: I want to replicate the accessibility behaviour of a UIAlertView, where the background view is still visible but VoiceOver does not interact with it.
Detail: I have implemented accessibility for an iPhone app, but have one problem remaining. In some cases I display a large view on top of all others (partially transparent, covering most of the original view) containing labels and a close button. i.e. basically a custom popup/alert view. The problem is, VoiceOver continues to reveal the views/controls underneath it.
One method to prevent the hidden views from being revealed by VoiceOver is to set the whole custom view background to be accessible. However, this isn't really what we want as this containing view shouldn't really be interacted with by the user, only its subviews (labels/buttons) should.
I think you should use this on your top laying view:
Objective-C
- (BOOL)accessibilityViewIsModal {
return YES;
}
Swift
accessibilityViewIsModal = true
This makes every element of the View Controller that is hidden unaccessible.
An implementation could be to set it to true when you show the view and set it to false when you dismiss that view.
More info
Note: Requires iOS5 and up
Swift 4
In swift try this:
Before your view is presented setup your viewController’s view like this:
yourViewController.view.accessibilityViewIsModal = true
Also try setting the self.view.accessibilityViewIsModal to true in viewWillAppear
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.accessibilityViewIsModal = true
}
It also might help if you send a screen chances notification when your modal or pop up view is appearing by adding this to the viewWillAppear:
UIAccessibility.post(notification: .screenChanged, argument: nil)
You can set the following properties on the view overlaying the background:
view.isAccessibilityElement = false;
view.isAccessibilityViewModal = true;
Does this work?
In obj-c:
view.isAccessibilityElement = NO;
view.accessibilityViewIsModal = YES;
When you hide the item, you can set isAccessibilityItem to NO.

UITableView how to "dim" the actual table when UISearchbar gets focus?

Many of the table searches I see actually dim (change alpha?) of the actual tableView when the search bar gets focused. I am trying to implement this.
When I overload
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
I am trying to do something like
self.tableView.alpha = .5f
But it is changing the alpha of the actual searchBar (if I have searchBar on its own) or changing the alpha of the entire table (including searchBar) if I have searchBar underneath the tableView in IB.
What am I doing wrong here. How can I just Dim the table and not everything.
I guess what I am really failing to understand is how all this stuff gets layered on the screen.
EDIT: The contacts application is a good example of what I am trying to do.
Most such apps just throw a black-background UIView on top of the table and fade it in (to an alpha of .5 or whatever) when the search bar gains focus.
If you use UISearchDisplayController, you get this behavior for free.
Since iOS 8 (and up to at least iOS 9.2) you would use a UISearchController. Unfortunately, currently the interface builder supports only the now deprecated UISearchDisplayController. So, this is how to add it programmatically to your table view controller, including the dim effect:
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
// Use the current view controller to update the search results:
self.searchController.searchResultsUpdater = self
self.searchController.dimsBackgroundDuringPresentation = true
self.tableView.tableHeaderView = searchController.searchBar
}

UINavigationController's back button disappears?

I notice something strange happens to one of my view controller: the back button disappears, yet it's possible to go back to previous view controller by tapping the top left corner (i.e where the button should reside).
In my entire file there's no line that set self.navigationItem.hidesBackButton to YES; also NSLog prints 0 as self.navigationItem.hidesBackButton's value in viewDidLoad.
This occurs in both the simulator and real device. Any ideas?
Oh dear. In the implementation of the previous view controller, I accidentally set self.title to #"", which causes this annoying bug.
Remove this line solves the problem.
I had a recursive navigation controller, and this also happened to me, I used this code to fix it:
self.navigationItem.leftItemsSupplementBackButton = true
Just in case someone is facing this issue with a custom back button and the above fixes did not work, here is a similar issue I faced with a different solution.
I had a customized back button with text that was disappearing while the arrow could be seen UINavigationController custom back button disappears from NavigationBar
So if anyone is facing a similar situation with disappearing back button text on a customized back button, here is my scenario and fix.
I customized my back button inside a custom NavigationController class as follows:
private func customizeBackButton() {
let backImage = UIImage(named: "BackButton")?.withRenderingMode(.alwaysOriginal)
navigationBar.backIndicatorImage = backImage
navigationBar.backIndicatorTransitionMaskImage = backImage
UIBarButtonItem.appearance().setTitleTextAttributes([
NSAttributedString.Key.foregroundColor: UIColor.panoStoryYellow,
NSAttributedString.Key.font: UIFont(name: "Montserrat-SemiBold", size: 15)!
], for: .normal)
}
This gave me:
Now when I tapped on the back button text, the text disappeared:
I made sure that I followed all the above answers such as setting titles making sure the tint color is valid etc. however this did not work.
In my case, I needed to set attributes even for the highlighted state of the back button as follows:
UIBarButtonItem.appearance().setTitleTextAttributes([
NSAttributedString.Key.foregroundColor: UIColor.panoStoryYellow,
NSAttributedString.Key.font: UIFont(name: "Montserrat-SemiBold", size: 15)!
], for: .highlighted)
After this, the back button text never disappeared