Cannot edit brand new UITextField - swift

I just made a new Swift project, put some text fields and a couple buttons in it, and when I start the app I cannot seem to be able to edit the text fields. Like the text fields are not taking any input. Any of them!
At the moment this is my only code. There should be nothing wrong with it. I literally ran the same code on another app and everything worked perfectly.
#IBOutlet weak var monthlyTF: UITextField!
#IBOutlet weak var annualL: UILabel!
var year = Double()
#IBAction func calculateAnnB(_ sender: UIButton) {
if let monthlyInc = Double(monthlyTF.text!){
year = 12*monthlyInc
annualL.text = "\(year)"
}else{
annualL.text = "That's not a number!"
}
}
There are other buttons and text fields in the app but I have not linked them yet because I didn't get to that part. I just wanted to test it piece by piece. Should I link them all first and then try?
It should be a really simple project. I don't know why I keep getting stuck on stupid technicalities like these.

Try what dinosaysrawr said, and also make sure User Interaction Enabled is set to true in the storyboard (under "View" in the Attributes Inspector).

Try deleting and reinstalling the UITextField in the storyboard
Edit: Also, make sure that the textField is enabled in the "Attributes Inspector" under "Control". If it's not enabled, it'll be grayed out and you can't tap on it to edit it

Related

UITextView dataDetector is not working in tableViewCell

I have a UITextView in a TableViewCell and I wanted to enable data detection in the textView in order to show clickable links and Phone numbers.
So I did this in storyBoard
These steps didn't work so I did the same in code.
#IBOutlet weak var postDescTextView: UITextView!
override func layoutSubviews() {
super.layoutSubviews()
postDescTextView.isUserInteractionEnabled = true
postDescTextView.isSelectable = true
postDescTextView.dataDetectorTypes = .all
}
But none of the steps seems to work.
There is clearly something I'm doing wrong. I'm pretty sure the answer is a simple one. I've found some similar questions like these.
Question 1
Question2
But unlike these questions, I don't want my TextView editable nor I don't want to be able to select The TableViewCell. Just need to make the Datalink detection work in a TableViewCell.
If you're trying to make postDescTextView programmatically remove everything else and add the following.
postDescTextView.isEditable = false
postDescTextView.dataDetectorTypes = .all
Or if you have a storyboard
Note: If you're using the programmatic approach there is no need for giving it in viewDidLayout which gets called every time there's a layout change. Give it in the init method instead.

Prevent VoiceOver From Reading UIButton as "Possible Text"

I am writing a very simple game that is designed specifically for blind users, but may also be used by sighted users. It uses many buttons as elements, however, blind users interact with these buttons through custom gestures (pan, tap, etc), so standard voiceover interaction is not appropriate.
The issue lies in the fact that there are no accessibility objects on the screen at all, so whenever the game loads, voiceover starts reading the labels on buttons (e.g. "Possible text: back, menu...). These buttons are read regardless of the fact that they are not enabled. I also can't remove most of them from the view for blind users.
I have tried turning off accessibility for the elements, unchecking "button" from accessibility traits, everything has allows direct interaction selected, I have tried .accessibilityElementsHidden, all the suggestions from How do you exclude a UIButton from VoiceOver? and nothing seems to work.
My current solution has a clear UILabel with no text in it, this is set to the only item in the .accessibilityElements array, and then for good measure I post an accessibility screen changed notification with that label as the object so it becomes focused, then I wait a second in a dispatch queue async after call, remove the label entirely, and set focus back to the main view so the user can interact.
Here is an example of my current solution:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.accessibilityElements = [lblVoiceOver!]
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIAccessibility.post(notification: .screenChanged, argument: lblVoiceOver)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.lblVoiceOver.removeFromSuperview()
UIAccessibility.post(notification: .screenChanged, argument: self.view)
}
}
This is a silly hack, at best, and I would love to implement a real solution that simply prevents the "Possible text" from being read by voiceover. I believe the possible text feature was added in iOS 11, to help apps that are not written with accessibility in mind to be more accessibility friendly, but so far I haven't found a way to turn this off.
The issue lies in the fact that there are no accessibility objects on the screen at all.
If you want to reach this purpose, just write self.view.accessibilityElementsHidden = true in your view controller that will contain no accessible element for VoiceOver anymore: this will indicate that the content of your container isn't accessible.
blind users interact with these buttons through custom gestures (pan, tap, etc), so standard voiceover interaction is not appropriate [...] I would love to implement a real solution that simply prevents the "Possible text" from being read by voiceover.
... following the preceding rationale, you should prevent VoiceOver from analyzing and reading anything in your view.
Now, dealing just with your buttons, I created a blank project with a simple code for the view controller hereafter (Swift 5.0, iOS 12):
import UIKit
class NonAccessibleButtonVC: UIViewController {
#IBOutlet weak var aboveLabel: UILabel!
#IBOutlet weak var belowLabel: UILabel!
#IBOutlet weak var myButton: UIButton!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
myButton.accessibilityElementsHidden = true
}
}
... and you get the following result on your device:
The button isn't taken into account as an accessible element and if it doesn't work in your code, it means that anything else prevents this correct operation. Add maybe the setAccessibleElement button property value to false according to your context ?
However, another solution could be defining the display of the desired accessibility objects in your view thanks to its accessibilityElements property taking away the buttons for instance (see Example 2 of this link): that will definitely work in addition to ordering all your elements.

Swift doesn't set text in UITextField after the update to swift 3

I updated my XCode to Swift 3 last week and it converted all my code to Swift 3 version. After that I am trying to set a text inside a UITextField and it doesn't work. I have already redone the connections from the UI with the code but it doesn't work.
When I type inside the UITextFiled it appears, but when I try to set the text programmatically it doesn't.
#IBOutlet weak var codigoTextField: UITextField!
codigoTextField.text = "3654"
I don't know what happened, but I rebuilt all the UI and remade all the connections and it worked.

Using string for comparison in "if" statement not working (SWIFT)

So I am in the process of developing this app for Mac and I am using Swift. I am just learning + developing the app side by side. I have the main viewController and when you press (+) button, it opens another viewcontroller with textfield. Now i have two buttons, one says "Done" and the other says "Cancel". If you press Cancel the viewController dismisses. However, if you press "Done" then whatever you added in that textfield appears in the first ViewController.
I want to run an if statement on "Done" button. So if you haven't written anything in the textfield and you press done, it gives you an error, and if you have written something, then it allows you to press Done and it dismisses!
I created an IBOutlet for the textfield:
#IBOutlet var weblinklabel: NSTextField!
Then whatever is stored in the weblinklabel is stored in another variable:
weblinklabel.stringValue = done!
Obviously, "done" is an optional string variable, assigned as this:
var done: String? = ""
Now in my understanding, "done" variable if empty should give the error which in this case is a label that shows itself(which is isHidden = false' in viewdidload()) function initially.
This is the "if-statement" that I am trying to use:
if done != nil {
self.view.window?.close()
} else {
label1.isHidden = false
}
I believe the placement of this code isn't right. I am placing it under IBAction of the "Done" button.
Any help in this regard, will be appreciated! thanks
The easiest way to do it would be to use a method similar to what I've explained in another response here.
Basically you would check in controlTextDidChange(notification:) if the content of the text field is "right" and if it's not you disable the Done button. Conversely you enable it if the text field validates, obviously.

Use NSPanel for user input. Not opening up again

I want to display a 'NSPanel' for the user to input a name for a new folder. Why a NSPanel? Because it looks awesome! It hosts one TextField and one PushButton to confirm the name. It shall also close the window when clicked.
It displays when the "add" button gets clicked in my menu. It also closes when the "done" button gets clicked in the NSPanel. But when I click "add" again it doesn't show up anymore. That also occurs when I close it via the normal "close button" in the title bar. So it is not explicitly related to the "done"-PushButton. I also tested implementing func windowWillClose(notification: NSNotification) which also doesn't get triggered in either cases. What could be the problem? Also, does it somehow need to be a "new" window every time? Or am I using this correctly for user input? I mean it just gets instantiated once and then "shown" and "unshown" or am I wrong?
So I did a new Cocoa-Class - Subclass of NSWindowController - and let xCode create a .xib for that also. In that .xib I "designed" the NSPanel. I ticked visible at launch without that the window wouldn't appear when the menu button gets clicked. I also hooked up an IBOutlet for the NSPanelin my Cocoa Class. My Class at the moment looks like this:
import Cocoa
class NamingHUD: NSWindowController, NSWindowDelegate {
#IBOutlet var insertNameWindow: NSPanel!
#IBOutlet weak var nameTextField: NSTextField!
override var windowNibName : String! {
return "NamingHUD"
}
override func windowDidLoad() {
super.windowDidLoad()
insertNameWindow.center()
insertNameWindow.makeKeyAndOrderFront(nil)
NSApp.activateIgnoringOtherApps(true)
}
#IBAction func userSetName(sender: NSButton) {
print("Close button clicked")
insertNameWindow.close()
}
}
In my Main Class I declared it as a variable like this:
var namingHUD:NamingHUD!
and then in override func awakeFromNib() as:
namingHUD = NamingHUD()
as well as in a click handler like:
#IBAction func addClicked(sender: NSMenuItem) {
namingHUD.showWindow(nil)
}
Now. When I click and addClicked() gets called the window shows up as expected. Fine! I enter a name and hit the "done" button and it closes the window properly. Also Fine! But when I click again, say to add another folder, the window doesn't show up anymore. I also created a Preferences Window the exact same way. But with a Window instead of a NSPanel inside. That totally works as it should.
So I clearly confused something or forget something. What could it be? I openly admit that it is the first time I am working with any kind of window outside of following a tutorial. So I clearly didn't grasp the whole concept of it. I read up about windows in Apples Developer Guide and it kinda makes sense. But... well, doesn't work at the moment. Am I "misusing" the NSPanel? Shouldn't be the case as it inherits from NSWindow or?
Did you connect the window outlet of NamingHUD to your awesome panel? Nibs are loaded lazily:
namingHUD = NamingHUD() // init the controller but doesn't load the nib
...
namingHUD.showWindow(nil) // now you are loading it for the first time
It works the first time because showWindow() loads the nib and show the window referenced by the window outlet. Your panel shows up because it's set to "Visible at launch". Your of course had no window to show.
Subsequent clicks don't load the nib file again, only order the window outlet to show up. That's why your panel did not show again. FYI: an NSPanel is a subclass of NSWindow so it has everything that NSWindow has, and then some more.