How to observe text change in UITextField using RxSwift? - ios

I want to observe any change of the UITextField.text property using RxSwift.
I trying to use rx.text property, but it called only when I set text property like this: textField.text = "", but not working when I typing text.
Also I tried to use rx.observe(String.self, "text"), but it gives the same result.
How can I observe any change of the text in UITextField?

To observe any change of the text in UITextField you can create extension for Reactive class:
public extension Reactive where Base: UITextField {
public var textChange: Observable<String?> {
return Observable.merge(self.base.rx.observe(String.self, "text"),
self.base.rx.controlEvent(.editingChanged).withLatestFrom(self.base.rx.text))
}
}

Related

How can I extend UITextField without losing functionality?

I need to extend my UITextField class in order to store some additional properties:
class UICustomTextField : UITextField{
var item = Item()
}
But when I do this:
let textField = UICustomTextField()
The keyboard covers up the TextField. Without extending the class it and use of UITextField directly it works.
There is any workaround ?

How to unclear UITextField secure text entry in Swift?

When I use default Security text Entry in UITextField in Swift Language after type type text once UITextField.
Once loss focus from UITextField after try to edit Secure text then UITextField is first reset and after it start put new text in UITextField.
How to edit old Secure Text without Storing data into Any Kind of String object
I'd suggest to create a custom UITextField class and override become​First​Responder() method do add your desired functionality:
You can override this method in your custom responders to update your
object's state or perform some action such as highlighting the
selection. If you override this method, you must call super at some
point in your implementation.
The custom Class should be similar to:
class CustomSecureTextField: UITextField {
override func becomeFirstResponder() -> Bool {
super.becomeFirstResponder()
if !isSecureTextEntry { return true }
if let currentText = text { insertText(currentText) }
return true
}
}
The logic of the implementation of becomeFirstResponder as follows:
By default, the secured-entry text field clears the inserted text when it is become first responder text, so what's happening in CustomSecureTextField that if the text field is secured-entry, it will re-insert the current inserted text -after clearing it-, but you have to make sure that the text field input is secured (that's the purpose of adding if !isSecureTextEntry { return true }) or the text will be duplicated (re-inserted) each time the text field becomes first responder.
Output:
Note that both of text fields are types of CustomSecureTextField:
This answer helped me to figure out this problem.
textField.isSecureTextEntry = true
following property not gonna work if you make testField isSecureTextEntrysecure property makes true .
textField.clearsOnBeginEditing = false
There is an issue with the #Ahmd F solution when you simply tap on the field it will automatically add the text to the field I have resolved that in the below code thanks
override open func becomeFirstResponder() -> Bool {
super.becomeFirstResponder()
if !isSecureTextEntry { return true}
if let currrentText = text {
self.text = ""
insertText(currrentText)
}
return true
}

How to localize Accessibility Label(Description) with Interface Builder?

In order to add VoiceOver support for my app(using Interface Builder),I set a button's "Accessibility Identity -> Description" to "Mute" like this.This actually set accessibility label.
And now,I want to add localization for this button,including accessibility label of it.
How can I do that?
ps: I've tried the programmatically way(NSLocalizedString) and creating xib file for each language.But both of them are not good for maintenance.I want to know if I can localize it in ".strings" way
You can create extension like this and then set keys in UI Builder but handle localization in .strings file
#IBDesignable
public extension UIView {
#IBInspectable
var accessibilityLabelKey: String {
get { return "" }
set {
self.accessibilityLabel = NSLocalizedString(newValue, comment:newValue)
}
}
}

Need to get placeholder text of UITextField

Is it possible to get the placeholder value of UITextField, which is designed in storyboard?
I need to validate the form which is having more textfields, so instead of giving static value, I want to give placeholder string of particular textfield as alert message.
Use the placeholder property:
textField.placeholder
For placeholder first you should create IBOUTLET for textfield and then do:
if let str = textfiled.placeholder {
if !str.isEmpty {
//do something
}
}
The UITextField class has a placeholder property. To reference the UITextField in code, you'll need to create an outlet for it in your view controller.
If you named the outlet myTextField, you could reference the placeholder like this:
let placeholder = self.myTextField.placeholder
Its work ...
For getting placeholder text you need to wire up your textfield with its IBOutlet object like,
#IBOutlet var txtField : UITextField?
Now you set Placeholder Statically or dynamically
self.txtField!.attributedPlaceholder = NSAttributedString(string:"Good", attributes:[NSForegroundColorAttributeName: UIColor.grayColor()])
After that anywhere you can simply get its placeholder text and compare or validate ur textfield like
if((self.txtField!.placeholder! as NSString).isEqualToString("Good"))
{
// Do here Whatever you want
}
else if(self.txtField!.placeholder!.isEmpty == true)
{
// check its empty or not
}
Simply write like below code,
if((self.myTextFiled!.placeholder! as NSString).isEqualToString("AnyString"))
{
// your code here
}

UITextField delegate methods are not fired when setting text programmatically

I've created a custom input view for entering text into UITextField. Basically it's just custom designed number pad. I have textfields, on which I've set the inputView property to use my custom created UIView subclass. In that view I have collection of buttons - from 0-9 and also backspace.
Now I want to change the text of UITextField programmatically when those buttons are tapped. The UITextField adopts UITextInput protocol, which in it's turn adopts UIKeyInput protocol. In that protocol I have all the methods I need, i.e. inserting text into cursor position and deleting text.
The problem is that those methods do not fire UITextField delegate methods. That is if I have custom validation in textField:shouldChangeCharactersInRange:replacementString: field for instance, that won't work. I've tried to set the text property of UITextField directly, but that didn't work also.
What is the right way of inserting text into UITextField, I mean insert text in a way that all delegate methods would be called?
Set the text of UITextField by calling insertText:
aTextField.insertText(" ")
I tried using textField:shouldChangeCharactersInRange:replacementString:without luck. I kept encountering a "bad selector sent to instance" crash when I tried invoking that method.
I also tried raising the Editing events, but I still never reached my breakpoint in my ShouldChangeText override of my UITextFieldDelegate.
I decided to create a helper method which would either invoke the text field's delegate (if exists) or the virtual ShouldChangeCharacters method; and based on that returning true or false, will then change the Text.
I'm using Xamarin.iOS, so my project is in C#, but the logic below could easily be re-written in Objective-C or Swift.
Can be invoked like:
var replacementText = MyTextField.Text + " some more text";
MyTextField.ValidateAndSetTextProgramatically(replacementText);
Extension Helper Class:
/// <summary>
/// A place for UITextField Extensions and helper methods.
/// </summary>
public static class UITextFieldExtensions
{
/// <summary>
/// Sets the text programatically but still validates
/// When setting the text property of a text field programatically (in code), it bypasses all of the Editing events.
/// Set the text with this to use the built-in validation.
/// </summary>
/// <param name="textField">The textField you are Setting/Validating</param>
/// <param name="replacementText">The replacement text you are attempting to input. If your current Text is "Cat" and you entered "s", your replacement text should be "Cats"</param>
/// <returns></returns>
public static bool ValidateAndSetTextProgramatically(this UITextField textField, string replacementText)
{
// check for existing delegate first. Delegate should override UITextField virtuals
// if delegate is not found, safe to use UITextField virtual
var shouldChangeText = textField.Delegate?.ShouldChangeCharacters(textField, new NSRange(0, textField.Text.Length), replacementText)
?? textField.ShouldChangeCharacters(textField, new NSRange(0, textField.Text.Length), replacementText);
if (!shouldChangeText)
return false;
//safe to update if we've reached this far
textField.Text = replacementText;
return true;
}
}
self.textfield.delegate = self;
[self.textfield addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
/* Put Your View controller Object instead self when delegate methods are in another class */
/* textfield delagete called when text did view change */
-(void)textFieldDidChange:(UITextField *)textView
{
if(Condition You want to put)
{
//Code
}
else
{
//Code
}
}
As par this method you want to make custom Methods too.

Resources