Set NavigationBar title on next ViewController without visual bugs - ios

So I have a UICollectionView called WeatherVC that has a NavigationController.
WeatherVC segues to WeatherDetailVC which is UITableView upon UICollectionViewCell selection.
I want to set WeatherDetailVC NavigationBar title based on which UICollectionViewCell was selected.
This code below makes my whole NavigationBar just buggy.
Example: https://imgur.com/a/vOIbxK5
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? WeatherDetailVC {
let cities = ["City1", "City2", "City3", "City4"]
// cellPressed = 3 - for example this would work without bugs
vc.navigationItem.title = cities[cellPressed]
}
}
Variable cellPressed was set on cell highlight or tap. It behaves like this only in iOS 13 and only if I give it number based on cell tapped - if it is static, title changes with no visual bugs. I already tried creating functions inside WeatherDetailVC to change its title and calling them in prepare for:segue but it did not help whatsoever.
EDIT: My main problem is those bugs or glitches that comes with this solution. I have no problem with changing next VC title.

Since navigationBar title represents the title of the view controller, You can set it directly:
vc.title = cities[cellPressed]
Assuming cities[cellPressed] is tested and returning correct value

I figured it out. It happens because of the diacritic. If I assign title with diacritic character navigation bar just bugs everytime. Anyone know how to fix it?
EDIT: You can see this happening in IMGUR link that I provided. Character "รก" is in the title.

Related

UISegmentedControl Set Selected Index Without Animation

I have a UITabBarController with 3 views. Each view has a UISegmentedControl in its navigation bar, and all of these segmented controls need to remain in sync. Each time the selectedSegmentIndex on one of them changes, I fire an event that causes the others to change their selectedSegmentIndex as well. I also set the index in viewDidLoad to ensure it is correct the first time the view is displayed.
This all works as expected, except that when I switch to a different view I can see the segmented control animate its button to the correct position, even though the selectedSegmentIndex may have been set much earlier.
Can anyone tell me what is going on here? Is there a way to disable this animation (when setting the index programmatically)?
Here is the working solution from the comments:
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
UIView.performWithoutAnimation {
segmentedControl.selectedSegmentIndex = 0
segmentedControl.layoutIfNeeded()
}
}
I know this answer is very late but in case anyone else needs same solution;
Layer of subviews of SegmentedControl has their own animation. Which are;
SelectionScale
SelectionPosition
SelectionBounds
here is a sample code from my project, I wrote whole new class for my UISegmentedControl
let foregroundIndex = numberOfSegments
if subviews.indices.contains(foregroundIndex),
let foregroundImageView = subviews[foregroundIndex] as? UIImageView {
foregroundImageView.layer.removeAllAnimations()
}
this is going to remove all animations over the selected UISegment and there will be no transition, it'll just snap.

How to hide title near the navigation icon in navigation bar ios swift

I am developing an ios application using storyboard and swift. I have a small issue with the title near the navigation icon not hiding.I am setting the code like self.navigationController?.navigationItem.backBarButtonItem?.title = ""
But it also not worked. I have attached the screenshot. How to fix this?
Add the below code in your viewDidLoad method
self.navigationController?.navigationBar.topItem?.title = ""
Note : This will remove back button title of current viewController and also it will clear the title of previous ViewController (where the back button is going to), so you have to set the title in viewWillAppear of previous ViewController if you want.
This is pretty simple to do. But first a little of theory. The backBarButonItem does not affect the current ViewController, it affect the next in the stack of the UINavigationController. I will give you an example. If you have the ViewController A and the ViewController B, then to accomplish your task, you set the backBarButtonItem in A with a blank space in the title. Then when you go A -> B you will see only the arrow in the top left corner.
Exist two way to solve this issue, one in the storyboard and the other is in code.
For the storyboard you need to set like in the next picture the Back Button title with an single space like you can see
The second way is in code, but for this you need an extra code get the dismiss appropriately
First put this code anywhere in your project
extension UIViewController {
#IBAction func unwind(_ sender: UIStoryboardSegue)
{
}
}
With that, then in A ViewController you can do then this:
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: self, action: #selector(unwind(_:)))
}
}
Good coding. Best regards

Navigation bar buttons set during viewDidLoad don't appear until after view has appeared in iOS 11

In iOS 10, I could determine the list of navigation bar buttons I want to appear in viewDidLoad, and they would appear in the navigation bar as the view controller transitioned in.
In iOS 11, I can no longer do this. Whatever navigation bar buttons were set in interface builder are displayed as the view controller transitions in, and my custom list of buttons are not displayed until after the view finishes sliding in. Updating the buttons in viewWillAppear does not help.
Is this simply a bug in iOS 11, or is there something else I should be doing? Is there a workaround so I can continue to display buttons while the screen loads?
In the following example, I have set a button "Default Button" in the storyboard, and override it with an "Edit" button in viewDidLoad. The project is available on Github.
iOS 10
iOS 11
It looks like the issue is that navigation bar icons displayed during the transition appear to be fixed when the view controller is passed off to the navigation controller. By the time that viewDidLoad is called, the icons have already been fixed.
In order to fix this, we need to update the navigation bar icons on the view controller's navigationItem before the view controller is pushed onto the navigation controller stack.
One way to do this would be to setup the navigation bar icons in awakeFromNib. This is what #Joe's answer was effectively doing, because apparently viewDidLoad is called from awakeFromNib when isViewLoaded is true during awakeFromNib.
However, doing this in awakeFromNib prevents you from taking into account any properties set on the view controller in prepareForSegue. So another option (and the one that I am using) is to force the entire view to load in prepareForSegue by adding the line _ = controller.view after setting any desired properties.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController
...
_ = controller.view
}
}
}
Move your Edit barButton code from viewDidLoad to isViewLoaded method as below.
override var isViewLoaded: Bool {
self.navigationItem.rightBarButtonItem = self.editButtonItem
return true
}
Output:
Note: Above code will fix the transition delay issue. Really, don't have much to explain why this happening. I experienced similar issue in iOS 10 as well NavigationBar delay updating barTintColor iOS10. It could be another bug in iOS11.
PS:
After reading Apple Doc about isViewLoaded and comparing other view loading methods. Its all about loading memory upon view loads.
You don't really need to move you barButton code at all.Just implement the isViewLoaded method and return to true as below:
override var isViewLoaded: Bool { return true}

Xcode: TableView cell to create ViewController

I've recently started using Xcode and Beginner to creating apps. I've come across something I'd like to implement but research hasn't been quite clear/complicated to understand.
I have a TableView with Days of Week and also a segmentedControl that duplicates these days 3 times. I'm wondering how I'm able to get user click to take me to an alternative ViewController depending on which day it is and what segment of the segmentedController is selected without having to create 21 viewcontrollers in the storyboard.
I've used a ViewController and made an outlet to a tableView for this setup.
in you tableview delegate method -> didSelectedRowAtIndexPath
you can simply write
let vc = UIViewController()
/*
you can add informations here
*/
present(vc, animated: true)
and inside this method you can use the indexPath to get the cell you've clicked
let cell = tableView.cellForRowAt(indexPath)
now you can get the information in this cell
You can have one viewcontroller which is basically a recipe for the viewcontroller you want to go to.
For example you want to show a viewcontroller with a label that states a combination of the number from the segmented control and the date which the user tapped on.
If you now create a ViewController which has a label in storyboard, the text on the label doesnt matter, you can use code to change the text to anything you would like.
In the tableviewcontroller you can use the didSelect delegate method of your tableview to present the viewcontroller and set the label to the values of the segmented control and the cell which is tapped.
I think you just need some more information about iOS and programming in general, therefore I suggest you watch the following iTunes U course:
https://itunes.apple.com/us/course/developing-ios-10-apps-with-swift/id1198467120
It has everything you need to know
Create a detail view controller with two variables (Ex - dayName and selectedSegmentIndex). And in your current viewController "tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)" push detailsViewController with these details like this
let objViewController: DetailsViewController? = UIStoryboard.mainStoryboard().instantiateViewController(withIdentifier: "DetailsViewController") as? DetailsViewController
objViewController?.dayName = dayName
objViewController?.selectedSegment = segmentControl.selectedSegmentIndex
navigationController?.pushViewController(objViewController ?? UIViewController(), animated: true)

Why is my navigation item/bar very dark in colour?

I am building a help screen view controller of my app. It basically contains a UIWebView because I want to use HTML to display the help text. There is also another view controller which is kind of the "main" VC. There is a "Present as Popover" segue connecting the two.
From the IB, I see this:
I have an unwind segue that unwinds to the main VC. It will be triggered if the user taps the "Done" button.
And here is my code:
import UIKit
class HelpViewController: UIViewController {
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
automaticallyAdjustsScrollViewInsets = false
let htmlString = "You don't need to know about this."
webView.loadHTMLString(htmlString, baseURL: nil)
}
#IBAction func doneClicked(sender: UIBarButtonItem) {
performSegueWithIdentifier("exitToMain", sender: self)
}
}
And the unwind segues are working perfectly but the navigation bar is somehow very dark in colour!
I don't know what's happening here. I checked out this question
iOS 7 SDK - UI Navigation Bar is sometimes darker and sometimes not. But why?
The asker said that's because of a piece of code that he wrote but I swear I didn't use the same code as he did (from my limited obj-c to swift translation knowledge)!
Anyway, here is the relevant storyboard hierarchy thingy:
What causes this problem and how to fix it?
I solved the problem by setting the background colour of the UIWebView to white. And the navigation bar turns white!
I found this by observing how the colour changes when I scroll the web view up and down. I saw that initially it is kinda grey. But when I scrolled down to the white part of the web view, it changes to white. I deduced that the grey colour is actually the web view's background property and the navigation bar is kind of translucent.
And that's why setting the background colour to white fixes this issue.
Stretch the web view through the bottom of the navigation bar and set automaticallyAdjustScrollviewInsets to true. That would adjust the scroll view inset to show the content at the right content.
did you try this
self.navigationController!.navigationBar.translucent = true

Resources