I faced something and I cannot understand it.
In the tutorial which I watched, instructor press (cntrl + click) delegate option and drag it into ViewController class. Then, textfield options become like the photo. I searched for a lot and I found an explanation ,but I couldn't understand it exactly.
Explanation : To be able to use UITextFieldDelegate methods, ViewController class must adopt this protocol. However, before using any method, we have to choose this delegate option.
I cannot understand this option. What is the benefit of it ?
so in order to use it and understand it try out these steps:
1 adopt UITextFieldDelegate protocol to your class like so
class MyViewController: UIViewController, UITextViewDelegate {
2 implement callback methods for the UITextViewDelegate. For example:
//MARK: UITextViewDelegate
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
print(textField.text ?? "")
return true
}
These methods are made for managing and validating text from the TextView.
Maybe you should read about protocols.
Or if you don't understand why you are setting your delegate form the storyboard directly it's because this way you will not have an extra property declared in your class. I will be done seamlessly and you will not have this in your class:
#IBOutlet weak var myTextField: UITextField!
//...
override func viewDidLoad() {
super.viewDidLoad()
myTextField.delegate = self
}
First add delegate to your view controller as
UITextFieldDelegate
Only then the delegate functions can be used in the view controller.
And for the functions to work as expected,
You have to set the textfield's delegate as self. Eg
textfield.delegate = self
Setting the delegate of textfield as self is the programatic way of doing the same thing the instructor did (as you said).
Related
I'm quite new to Swift and couldn't find any good explanation for this. I want the user to select a duration (h:m:s) when clicking on a UITextField in an alert and display the value in the textField.
Can someone please give me a hint or an explanation.
UITextField has delegate protocol called UITextFieldDelegate
in your viewController:
func viewDidLoad() {
super.viewDidLoad()
yourTextField.delegate = self
}
Conform your viewController to this delegate. There is a textFieldShouldBeginEditing method, it is called when the user taps into the textfield. You return false here, so the textField won't became first responder and the keyboard will not open and you can present your picker.
extension viewController: UITextFieldDelegate {
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
//open your alert here
openPicker()
return false
}
}
You can use UIPickerView to present to the user. You can read about that here and even create it based on the example:
explanation and example of UIPickerView
Swift beginner here. I am having quite a tough time getting my UITextView delegate methods to call. I have looked through many other questions, to no avail.
I have a UITextView set up in a ViewConroller. It looks like this:
There is a UIImageView directly above the UITextView, and everything is wrapped in a navigation controller, should be no big deal.
I made sure to connect the View from the storyboard to my ViewController:
From the storyboard I CTRL+Drag the UITextView right below the class declaration. This produces the line:
#IBOutlet weak var Description: UITextView!
Class declaration:
class ImageTextViewController: UIViewController, UITextViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
(I need the other delegates for my NavigationController and UIImageView)
I then declare the delegate as so:
override func viewDidLoad() {
super.viewDidLoad()
self.Description.delegate = self
Now the following delegate method should be called when I finish editing the UITextView. But for some reason it is not firing!
private func textViewDidEndEditing(_ textView: UITextView) -> Bool{
print("we are done editing")
spotDescription.resignFirstResponder()
return true
}
How do I get that to fire properly for my UITextView?
textViewDidEndEditing method do not have return value. You have to write this
func textViewDidEndEditing(_ textView: UITextView) {
print("we are done editing")
}
Jack is right.
In the image titled Storyboard Connection your viewController seems to be titled TextImageViewController, while in the class declaration example is titled ImageTextViewController.
The ViewController in the Storyboard and the ViewController should both be the same.
Андрей is also right.
TextViewDidEndEditing method does not have a return value.
lindanordstrom also makes a good point:
TextViewDidEndEditing shouldn't be private.
For simplicity, let's say I want to create a custom UITextField and I want to add a simple behaviour to it; Which is, if the textfield becomes the first responder, the background color would be changed to green.
To do so, in my custom class I have to set the class as the delegate to receive the event of becoming first responder. But the thing is that if the user of this custom textfield set itself as the delegate the events are not sent to the custom textfield(Since only one object can be the delegate of another object)
I can manually forward all the events, but I'm looking for a cleaner and more scalable solution.
Here's a sketch of the situation:
class MyTextField: UITextField {
override func awakeFromNib() {
super.awakeFromNib()
delegate = self
}
}
extension MyTextField: UITextFieldDelegate {
func textFieldDidBeginEditing(textField: UITextField) {
backgroundColor = UIColor.greenColor()
}
}
but if the user of MyTextField do this:
class ViewController: UIViewController {
#IBOutlet weak var myTextField: MyTextField!
override func viewDidLoad() {
super.viewDidLoad()
myTextField.delegate = self
}
}
the behaviour won't work; because the delegation relationship to MyTextField is gone.
NOTE: I'm not only interested in becoming first responder problem, rather it's about using any methods of the delegate, with capability of the user of my custom UITextField setting itself as the delegate, at the same time.
Thanks, in advance.
As you say, most delegation is restricted to a single object as the delegate.
Since a text field is a responder, you should be able to override func becomeFirstResponder() -> Bool to change the color, while letting the user of the object handle the delegation as it expects.
UIResponder docs: "Subclasses can override this method to update state or perform some action such as highlighting the selection."
On one of my ViewControllers, I declared:
#IBOutlet var priceTextField : UITextField!
Then I tried to add the following based on the same UITextField:
#IBAction func priceTextFieldChanged(sender: UITextField) { updateOutput() }
When I looked at the XIB's File Owner and at the Received Actions, I was not able to connect the UITextField to this function for some reason. I even tried to drag that UITextField to the ViewController, but was not able to see the "Action" option. I checked the class. It's linked to the ViewController. Not sure what to do here.
Any advice?
A UITextField does not provide an action (sendAction:), that is why you can't hook-it-up.
What you need is to create a delegate, for textFieldDidBeginEditing or another delegate method of UITextField and set the UITextField delegate to your class instance.
#Zaph, something like this:
class ViewController: UIViewController,UITextFieldDelegate {
#IBOutlet var priceTextField : UITextField!
func textFieldDidEndEditing(textField: UITextField) {
if let value = sender.textIntegerValue() {
pricetepper.ifInRangeSetValue(value)
}
updateOutput()
}
}
Not sure if I pick the right method. Thanks.
I'm new in stackoverflow, I have a problem with new swift code.
I have custom the return button on keyboard with "Done", but when I tap on it, don't befall anything... How can I hide the keyboard on tap it?
I have added a code (found on this site) for hide the keyboard when you tap somewhere ,not in the keyboard, but I can't custom it with tap on "done" button... Thank you before!!
You need to implement delegate method which is called when you hit done button:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
You also need to conform to UITextFieldDelegate protocol:
// I assume you override UIViewController class. If not add UITextFieldDelegate to your class
class MyViewController: UIViewController, UITextFieldDelegate
The last thing is set up your class to be a text field delegate:
textField.delegate = self
textField.delegate = self
can be replaced by
This will create the necessary connections between your View, its component and will make the textFieldShouldReturn method work as expected.
The protocol methods have new signatures (Swift 4.1). IE:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
As the protocol methods are optional, using a wrong signature will silently fail.