How to enable/disable navigation bar buttons [XCode] (swift) - ios

I was wondering how I would be able to go about changing the status of buttons. I want to make it if one of two text fields has text in them then the button will become useable. I have currently turned off the button from the storyboard. The code I have to check if there is text inside of the text fields is as follows:
Disclaimer:
The code to check if the text field has any text in it works perfectly fine.
#IBAction func textFeildEditingChanged(_ textField: UITextField) {
if FirstName.hasText == true {
self.navigationItem.rightBarButtonItem?.isEnabled = true
print("First name isn't empty")
}
}
The current code that I have in there to set the button to enabled and disable doesn't work however the code to test if the text field has content does work. I just need to figure out how to disable and enable the button of a navigation item.
code that doesn't work is below:
self.navigationItem.rightBarButtonItem?.isEnabled = true
Any help would be greatly appreciated.
Edit: I am using a navigation controller, don't know if that's important or not.

If you are using the storyboard, just connect the outlet then disable it.
#IBOutlet var navigationItemButton: UIBarButtonItem!
then
navigationItemButton.isEnabled = FirstName.hasText

Related

Getting the value in the textfield in IOS Simulator

I am new to Swift and x-code. I'm currently developing an app where there is only one textbox and one submit button.
I am writing a test case which is like this- "Whenever i click the submit button, the text which is given by me in the text field should be validated."
How can i get the text from the textbox when i click the submit button? while running the test case
To find out when the button is clicked, you will have to define an Action for your button in some Target... usually your view controller. Search Apple’s documentation for the “Target Action” design pattern and you should find tutorial information.
To get the value of a text field, you can simply get it’s text property. However, to get a reference to the text field, your view controller will need an Outlet that references the text view. In the documentation you can search for “Outkests” or IBOutlet to find tutorials.
Create an IBOutlet for that textField and connect it in the storyboard (See attached file)
#IBOutlet weak private var textField: UITextField!
And use textField.text to get text file value in your IBAction that handle tap event
first create #IBOutlet of your text field and create #IBAction of submit button. and validate it in #IBAction like this :-
#IBOutlet weak var textfieldOutlet: UITextField!
#IBAction func submit(_ sender: UIButton)
{
if textfieldOutlet.text?.isEmpty == False
{
print(textfieldOutlet.text);
}
}
*set breakpoint on print value and you getvalue
In UI tests, you can access the text from an XCUIElement representing a UITextField using the value property.
let app = XCUIApplication()
let textField = app.textFields.element
textField.typeText("test text")
let text = textField.value as? String // should be "test text"

How to disable UIControlEventEditingChanged

I have a UIViewController with several UITextFields. When tap one text field, it should present the barcode scanning view controller. Once the scanning is completed, my barcode scanning viewcontroller is disappearing (used "dismissViewcontroller") and the scanned value should entered into the text field I tapped. This is working fine. I have set the delegate for each text field like this.
[field addTarget:metrixUIViewControllerIn action:#selector(executeScriptOnTextFieldChange:) forControlEvents:UIControlEventEditingChanged];
The problem is this :
Lets say I have set an alert to display inside this executeScriptOnTextFieldChange method. Once I tapped on the 1st text field, then the barcode scanner comes. Once I scanned barcode scanner closes and set the value for the first text field and fire the alert.Thats ok. But then if scanned by tapping the 2nd textfield and the string will set to that textfield and fire the alert related to 2nd textfield also fire the alert related to first textfield as well. I want to stop happening this. Is there any way to disable the delegate for one textfield? This happens because I am refreshing the view in the viewDidAppear. But I have to do that as well. Please help me.
UIControlEventEditingChanged for a textField can fire at many different events that are not even directly related to that textField, but related inderectly.
For instance, when your ViewController is presenting the barcodeScanner it may trigger a "resignFirstResponder" event on the textField. Also when the 2nd textField is tapped, cause the 2nd becomes first responder and the 1st suffers a "resignFirstResponder".
I suggest trying to use a UITapGestureRecognizer in your textField instead. Example:
Swift 4
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.tag = 1
self.textField.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(fireTextField(_:))))
}
#objc func fireTextField(_ sender: UIGestureRecognizer){
let view = sender.view
guard view != nil else{
//Do nothing
return
}
let condition = view!.tag == 1
if condition{
//or do whatever other stuff you need
self.textField.becomeFirstResponder()
}else{
//Whatever for other textFields
}
}
This way, you could use the "tag" attribute to determine which textField is firing and so adjust "condition". You could also filter the flow with a switch using the "tag".
Not sure if any of this will really help as I would need more info about the flow you need to accomplish. Hope it does help!

Disabled UITextView shows empty context menu on long press

I have a UITextView subclass where I specifically disable all context menu options:
class MyTextView: UITextView {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
}
I add an instance of MyTextView to a view that shows up in my app. I give the instance of MyTextView the following value: isEditable = false
When I long press on the UITextView however, I get the following:
This seems like a bug since there is nothing in this menu? Any ideas on how to prevent this?
Thanks!
Because selectable property is active. So you can "select" a part of text and iOS default behaviour is to show this popover.
You can disable this property by storyboard, or by code.
Storyboard:
At storyboard, select the textview and go to attribute inspector tab... Search for behavior and uncheck selectable checkbox.
or, if you prefer, you can solve it by code:
at viewDidLoad method, set the property isSelectable to false.
MyTextView.isSelectable = false
That's not "the menu". It's just the thing that magnifies the region where the press occurs:
It's empty in your screen shot only because you've no text, so we're magnifying nothing. The menu appears after your long press ends and the magnifier thing goes away — and it doesn't appear, so your code is working fine.
You can see easily that that's true by changing your code to return true. The empty magnifier will appear, just as it does now, and then when it disappears, the menu appears. Thus, we have proved that what you are seeing is not "the menu".

Prevent UISearchBarController to show UINavigationBar

I'm using a UINavigationBar ALWAYS hidden (I'm using NavigationBar facilities to push ou pop views but I'm not showing it to final user), the problem is that in one of those views I have a tableView with UISearchBar. When I select the searchBar, make a search and click on it's "Cancel" button the NavigationBar appears, but I want to keep the Navigation hidden as it is.
I've tried to hidden the navigationBar one more time by willDismissSearchController or didDismissSearchController by
func willDismissSearchController(searchController: UISearchController) {
self.navigationController?.navigationBar.hidden = true
}
but it did not worked as I want.
Thank you in advance.
I've found a solution, so as it is a unusual question I'll reply for other people know the solution.
the following code did worked for me:
override func viewDidLayoutSubviews() {
self.navigationController?.navigationBar.hidden = true
}

How do I connect custom keyboard to text field?

I created a custom keyboard using buttons, but now I'm stuck with buttons that don't do anything.
How will I connect them to a text field?
First, you should be aware of the inputView property of the UITextField/UITextView classes. Basically you can have a custom view (your keyboard for example) and swap it with the default keyboard.
You can get some inspiration from this tutorial that shows how to create a custom keyboard - and how to connect it to your textfield/textview.
You can also read this answer for another way to connect your keyboard to a textfield/textview.
You can handle buttons touchUpInside Action like this to insert text in uitextfield
#IBAction func btnQuestionAction(_ sender: UIButton)
{
self.textDocumentProxy.insertText("?")
}
And to delete character using custom keyboard, You can use this:
#IBAction func btnBackspaceAction(_ sender: UIButton)
{
self.textDocumentProxy.deleteBackward()
}
Hope it will help you :)

Resources