Dismissing a numeric keyboard - swift

A noob question here: I have read a lot about dismissing the keyboard from objects like labels or event when one taps the RETURN key or other areas of the screen. However, is there code to dismiss a keyboard from within a BUTTON? I tried various ways of ResignFirstResponder at the end of the code in my BUTTON but to no success.
Any help that can be shed would be appreciated. Please remember I a new to all this so I please be as specific as possible.
Thank you

You can send endEditing(_:) to the text field that is the first responder, or to any superview of it, to make it resign first responder and dismiss the keyboard. The window is a view, and is a superview of all your other views, and is easy to get a reference to:
#IBAction func calculateButtonWasTapped(sender: AnyObject?) {
view.window?.endEditing(true)
// perform calculation here
}

Let's just say that the text field is called theTextField, and when pressed the UIButton runs an #IBAction called buttonTapped().
class ViewController: UIViewController {
#IBOutlet var theTextField: UITextField!
#IBAction func buttonTapped(sender: AnyObject) {
theTextField.resignFirstResponder()
}
}

Related

Open keyboard without clicking on TextField on tvOS - Swift

I'm creating an app and I need to login to it and I don't want to use 2 Text Field for insert Email and Password. What I would wish to achieve is: click on the button "Log in", then it will open the classic full screen keyboard that is usually appearing when you are doing click on UITextField in tvOS.
Can someone please write an example of code on how to invoke the keyboard clicking on a UIButton instead of UITextField? Thanks a lot!
While your UI is questionable, once your first text field finishes editing, you could start the other one.
Set the first text field UITextFieldDelegate to the view controller, and then:
class ViewController: UIViewController , UITextFieldDelegate{
#IBOutlet weak var tf2: UITextField!
#IBOutlet weak var tf1: UITextField!
#IBAction func click() {
tf1.becomeFirstResponder()
}
func textFieldDidEndEditing(_ textField: UITextField) {
if (textField == tf1){
tf2.becomeFirstResponder()
}
}
}
If you want a UITextField to open up the keyboard without the user having to tap on it, you can use yourTextField.becomeFirstResponder().
I don't think you can present the keyboard without any associated input view

Detect backspace in empty UITextField Swift Working Sample

I know that this question may sounds duplicate, but looking at the several answer, nothing is working for me yet.
Basically I have a Quizz App, a question is shown and the user needs to fill several UITextFields to answer the question (i.e. if the answer is VENICE, 6 UITextFields will be shown, 1 per letter).
It was able to detect one character in the UITextFields and once the user hits a key it will jump to the following UITextField. I use the tag of the UITextField and the method becomeFirstResponder.
The problem is that I will like to detect the backspace when a UITextField is empty so I will jump to the previous UITextField.
I have tried this solution from Jacob Caraballo (Detect backspace in empty UITextField) but I am not sure, how to use it with my existing UITextField.
For example, I have tried:
// #IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField1:MyTextField!
But calling the delegate
textField1.myDelegate = self
It crashes
I also notice, that using the Jacob's solution I won't be able to check which UITextField was used as the func textFieldDidDelete() doesn't not have an UITextField as parameter and I will need to check its tag i.e.
If textField.tag == 5 {
textField4.becomeFirstResponder()
}
Any help on this please?
If you use Jacob's solution, the deleteBackward method will be called with the current UITextField instance. So you can add a protocol to that UITextField class and pass it back to your view.
Something like this:
protocol MyTextFieldDelegate: class {
func backwardDetected(textField: MyTextField)
}
class MyTextField: UITextField {
weak var myTextFieldDelegate: MyTextFieldDelegate?
override func deleteBackward() {
super.deleteBackward()
self.myTextFieldDelegate?.backwardDetected(textField: self)
}
}

Adding views with IBAction to a NSStackView crashes application

I want to use the NSStackView to stack views above each other, I also want them to de able to expand so I can't use the NSCollectionView if i understood it correctly.
So, in storyboard, I've created a NSStackView(embedded in scroll view) in the main view controller and a view controller that I want to fill it with:
The button will fill the stack view with ten views:
#IBOutlet weak var stackView: NSStackView!
#IBAction func redrawStackView(_ sender: Any) {
for i in 0..<10 {
let stackViewItemVC = storyboard?.instantiateController(withIdentifier: "StackViewItemVC") as! StackViewItemViewController
stackViewItemVC.id = i
stackView.addArrangedSubview(stackViewItemVC.view)
}
}
And the ViewController on the right simply looks like this:
class StackViewItemViewController: NSViewController {
var id: Int = -1
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
}
#IBAction func buttonPressed(_ sender: Any) {
debugPrint("StackViewItemViewController" + id.description + "pressed")
}
Running this small application works fine, every time I press the button ten more stack view items appears. But, when I have the audacity to press one of the buttons to the right the application crashes:
Where am I going wrong?
I have tried to work around the IBAction to verify that this what breaks, and the application will not crash if I subclass the button and make a "buttonDelegate" protocol with a function being called from mouseUp.
I guess the problem is that the viewController objects, which you create in the loop, are released immediately.
Even though the view is attached to the stackView, it's viewController is destroyed.
You can fix this issue by keeping a reference to each viewController.
You can do this by creating a new variable
var itemViewControllers = [StackViewItemViewController]()
and then add each newly created viewController to it:
itemViewController.append(stackViewItemVC)

Edit button does not have any functionality, no red circle with a minus appears on the left side of cells

I have looked at another question that was asking the exact same question as mine, but the answer told them to call the setEditing function (which I tried, and say later in the question). But I don't see how you could call this function only when the edit button is clicked. I suppose I could create my own BarButtonItem and run this method when my bar button item is clicked, but I figured this would be far easier since I need the basic functionality of the edit button.
I have a UIViewController that has a table on it named peersTable. When I click the edit button it switches to done, but nothing happens on the table. I have also added my own UITableViewRowActions and when I swipe to the left on the cells, my custom actions do show up.
Here is some of my code:
class PeerViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, ConnectionManagerDelegate {
#IBOutlet weak var peersTable: UITableView!
...
override func viewDidLoad() {
...
peersTable.delegate = self
peersTable.dataSource = self
self.navigationItem.rightBarButtonItem = self.editButtonItem
...
}
I have also tried calling the peersTable.setEditing(true, animated: true) method myself, and in this case, the red minus does appear. I've never seen this issue before, so I don't understand why it's happening. Am I somehow setting the delegate wrong? Or possibly I'm doing something wrong since this is a regular View and not a TableView (even though I've done this before in a previous project).
Thanks in advance! If you need any more information let me know!
Since this is a not a TableViewController it won't automatically set your tableView to editing mode when you press the edit button.
You need to override setEditing method so you can set the tableView to editing mode.
Add this to your ViewController class:
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
peersTable.setEditing(editing, animated: animated)
}

IBOutlet and IBAction in Swift

I connected a IBOutlet and IBAction to my button variable from Interface Builder to my View Controller. How do I add an action method to the button in Swift?
This code doesn't seem to work.
#IBOutlet var OK: UIButton!
#IBAction func OK(sender: UIButton){}
The Objective-C equivalent I found is:
#interface Controller
{
IBOutlet id textField; // links to TextField UI object
}
- (IBAction)doAction:(id)sender; // e.g. called when button pushed
When you attach a button to the viewController and create an action (IBAction) using ctrl-drag, you create a method that looks likes this in Swift (if it doesn't have arguments):
#IBAction func buttonAction() {}
In Objective-C the same thing will look like this:
- (IBAction)buttonAction {}
So that means that #IBAction func OK(sender: UIButton){} is an action method.
If you want to know about the sender argument, I would recommend this SO post.
Edit:
For what you want to do, I create an IBOutlet and an IBAction, that way I can change its attributes with the outlet variable, and have the action side of things with the IBAction, like what you show above:
#IBOutlet var OK: UIButton!
#IBAction func OK(sender: UIButton){}
For example, if I want to hide the button, I would put this code in the viewDidLoad
OK.hidden = true
The OK in that code is for the outlet variable, if I wanted to print "You pressed me" to the console when the button is pressed, I would use this code:
#IBAction func OK(sender: UIButton){
println("You pressed me")
}
Above I am using the action to print "You pressed me" to the console.
A few things to note:
When Swift 2.0 gets released println will get changed to print. Also with you action and outlet, I would suggest giving them differing names, to make it easier to differentiate the two, something like this:
#IBOutlet var okOutlet: UIButton!
#IBAction func okAction(sender: UIButton){}
Along with that, you should use camel case when naming variables, constants, functions, etc.
One way to do it, is control-drag from your button to your viewcontroller and choose action:
If you have connected your button's action, your code should work just fine.
Here are the steps you can follow-
For #IBOutlet
1.Declare Your Interface builder Element property right after class name
class SomeViewController: UIViewController{
#IBOutlet weak var aTextField : UITextField! ////Your Interface builder Element
2.Hook the IB Element From Storyboard.
For #IBAction
1.Write A method inside your class(say SomeViewController)
#IBAction func anAction(_sender : AnyObject){
}
2.Hook the method from Storyboard.
Hope it might helps.
You can simply add action from your storyboard. See the image.