I want to use a UITextField so that only part of it will be editable.
I know about the delegation and shouldChangeCharactersInRange but for some reason, copying the ranged part is allowed.
My goal is to get similar result to this (the 'subject' text part) without being able to copy it.
Should i use a different UITextField with textFieldDidBeginEditing returning false all the time?
Is there a better solution?
In the screenshot, a UILabel placed next to the UITextField is used. I'd recommend doing this as it will give you more options when you decide to style the text.
Related
I would like to create grouping with kerning in a UITextField. I use shouldChangeCharactersIn delegate method to be able to react to every text change. I format my text then assign it back to the attributedText property of the textfield. It works great but I have a small bug which I don't understand. When I leave the cursor after a character which has different kerning (lets say 4) then the default (around 1) and the textfield loses the focus that default kerning changes to the one which was before the cursor (4). Any idea why is this happening? How to solve this problem nicely?
I have noticed that if I nil out the property selectedTextRange in textFieldShouldEndEditing then this bug disappears but It just doesn't seem nice to implement this method just because of this.
Source code of this ViewController can be found here.
I often want to put my own things in the same place the keyboard pops up, but for my own controls... such as putting a UIDatePicker there, or a custom UIPickerView, or whatever.
I came up with a clumsy way of getting this behavior by having a dummy UITextField and putting my custom view in its inputView property. Then when the user clicks on my item, I just trigger off the UITextField to display the view I've assigned to the inputView.
Then I got to wondering if there was a better less kludgey way to do this. I found this article Show UIPickerView like a keyboard, without UITextField where several people recommend the same thing I do.
My question is this. Is it common to (mis)use the UITextField in this manner?
Many times you will face a UITextfield that you would want to populate through a custom control other than the standrd keyboard. Thus the inputView method was declared and can be used.
What is recommended:
1- if the UItextfield is normal, use the keybard (don't change the input view)
2- if the value is numeric, show the numberpad in keyboard directly (textField.keyboardType = .numberPad)
3- if your textField is a date then you set the input view as a date picker.
4- sometimes you need a UITextField where you need to choose between stuff. Thus you develop your own custom UIPicker and set it as an input View.
5- If what you are tring to achieve don't fall in all the above then you can do your own inputView and assign it.
So in short don't be afraid, it is the normal thing to do!
Hope this helps!
Please give me a hand~ I wanna know how to make UILabel have a system Clipboard(e.g. copy and select) like UITextField (UITextView、UIWebView) when it has a long press, which makes me can copy the text I want. I have read some demo on Github, however, they always only contain copy function, which makes me can't choose the text I want to copy. At present I wanna implement "select" on UILabel but I don't know how to work out.
Can I use UITextField without editing function? But once I turn off editing function, there is no system Clipboard when it has a long press.
Or if there is a simpler method to work out? Thanks!
You're gonna have to implement it yourself. There isn't anything too special about any of the system text views, just read the docs for UIPasteboard, specifically around -[UIPasteboard setString:]. The rest just comes down to how you want to implement the UI. For that I'd recommend looking into subclassing UILabel just to keep everything tidy; UIMenuController for showing the callout view; implementing -canBecomeFirstResponder, -canPerformAction:forSender:, and -copy: to customize the callout actions; and UILongPressGestureRecognizer for triggering everything.
I know how to disable the standard copy, paste, cut... options in Swift when editing a UITextField's / UITextView's text but I don't know how to do this with a UISearchBar. With a text field I would subclass UITextField and override the canPerformAction() method. But when subclassing UISearchBar this does not work and I don't know how to address the searchBar's textField. Furthermore I would really like to know, how you could change the color of the little 'X' on the right site of the search bar's text field, which is responsible for deleting all the text in the text field.
Would be great if someone could help me with these two things. Thanks in advance.
Your best bet to change the clear button color is to use a custom image by calling
setImage(_ iconImage: UIImage?, forSearchBarIcon icon: UISearchBarIcon, state state: UIControlState)
on the UISearchBar.
As to disabling copy/paste on the UISearchBar's text field, I don't think there is a way to do that. Even if you get access to the UITextField instance contained in it, there's no way you'd be able to change the behaviour for that particular instance.
If I want to handle changes to a UITextField, such as the user typing in it; it seems like this can be done either by assigning a delegate to that text field, and then having the delegate implement shouldChangeCharactersInRange, or by adding a target to the textField, and handling the UIControlEventEditingChanged event.
Aside from the fact that with the delegate method, you can return NO and therefor stop the user from making the edit, is there any difference between these 2 things?
Same question for handling the beginning of editing or the ending of editing. It could be done either with the appropriate delegate methods or with the appropriate events. What is the textField delegate actually for if the control events can do the necessary work?
shouldChangeCharactersInRange is called before a change occurs, and gives you opportunity to 'cancel' the change. UIControlEventEditingChanged is called after the change occurred.
You can determine the resulting value of the textField in shouldChangeCharactersInRange, but you have to manually apply the replacementString to the existing text, using the supplied range. (via NSString stringByReplacingCharactersInRange). If you want to know the resulting text, it's easier and more efficient to use UIControlEventEditingChanged.
shouldChangeCharactersInRange is often used to implement validation checking of input - that is, you can filter characters/pasted text as it is entered. If a field is for phone numbers, for example, you can return FALSE if the user types a non numeric character, or attempts to paste in text that isn't numeric.
You might find a case where you can reuse code for multiple controls if you can stick with the UIControlEvent-methods.
You're right; you can essentially do the same thing via both, but UIControl is lower level and lets you siphon off each particular UIEvent to different targets via [UIControl addTarget:action:forControlEvents:] where as there is only a single delegate.
I would also say that the UITextField delegate protocol is simply there as a more convenient, higher level alternative to UIControl/UIEvent as a way to manage the behaviour of a UITextField.
The most common delegate pattern is UITableView DataSource and Delegate and I would say that using the UITextField delegate protocol is quite similar and therefore looks far more straight forward with more defined intentions than handing the messages from UIControl directly.
One key difference I've found between the two approaches posed in the original question is that the delegate "shouldChangeCharactersInRange" gets called BEFORE the value in the UITextField changes. The target for UIControlEventEditingChanged gets called AFTER the value in the UITextField changes.
In the case that you're using these events to make sure (for example) that all fields in a dialog are completely filled in before enabling a "Done" button, the target approach may work better for you. It did for me.
The delegation approach is the way to homogenize UITextField and UITextView behavior.
UITextView does not have control events. In contrast, UITextFieldDelegate and UITextviewDelegate provide parallel methods.
I have found out that shouldChangeCharactersInRange passes the same NSRange for insertion and deletion of text. You append a space and then delete it, and the parameters from shouldChangeCharactersInRange are indistinguishable from duplication of the text.
So shouldChangeCharactersInRange actually cannot predict the resulting text.