How should I go about detecting if typing has stopped in a UITextField
? Should I use the UITextFieldTextDidEndEditingNotification
function of some sorts? I a trying to create a instagram like search where it will display the results after a second of not typing.
This is how I did and it works for me in Swift 3
import UIKit
// don't forget to add UITextFieldDelegate
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var textField: UITextField!
var searchTimer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
// declare textField as delegate
self.textField.delegate = self
// handle the editingChanged event by calling (textFieldDidEditingChanged(-:))
self.textField.addTarget(self, action: #selector(textFieldDidEditingChanged(_:)), for: .editingChanged)
}
// reset the searchTimer whenever the textField is editingChanged
func textFieldDidEditingChanged(_ textField: UITextField) {
// if a timer is already active, prevent it from firing
if searchTimer != nil {
searchTimer?.invalidate()
searchTimer = nil
}
// reschedule the search: in 1.0 second, call the searchForKeyword method on the new textfield content
searchTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(searchForKeyword(_:)), userInfo: textField.text!, repeats: false)
}
func searchForKeyword(_ timer: Timer) {
// retrieve the keyword from user info
let keyword = timer.userInfo!
print("Searching for keyword \(keyword)")
}
}
This approach uses an NSTimer to schedule a search 1 second after the text field changes. If a new character is typed before that second is up, the timer starts over. This way, the search is only triggered starts after the last change.
First things first, make sure the ViewController is conforms to the UITextFieldDelegate protocol:
//
// ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UITextFieldDelegate>
@end
Then, implement the timed search:
//
// ViewController.m
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textfield;
@property (strong, nonatomic) NSTimer * searchTimer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// declare this view controller as the delegate
self.textfield.delegate = self;
// handle the change event (UIControlEventEditingChanged) by calling (textFieldDidChange:)
[self.textfield addTarget:self
action:@selector(textFieldDidChange:)
forControlEvents:UIControlEventEditingChanged];
}
// reset the search timer whenever the text field changes
-(void)textFieldDidChange :(UITextField *)textField{
// if a timer is already active, prevent it from firing
if (self.searchTimer != nil) {
[self.searchTimer invalidate];
self.searchTimer = nil;
}
// reschedule the search: in 1.0 second, call the searchForKeyword: method on the new textfield content
self.searchTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0
target: self
selector: @selector(searchForKeyword:)
userInfo: self.textfield.text
repeats: NO];
}
- (void) searchForKeyword:(NSTimer *)timer
{
// retrieve the keyword from user info
NSString *keyword = (NSString*)timer.userInfo;
// perform your search (stubbed here using NSLog)
NSLog(@"Searching for keyword %@", keyword);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
swift
xcode - 10
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
NSObject.cancelPreviousPerformRequests(
withTarget: self,
selector: #selector(self.getHintsFromTextField),
object: textField)
self.perform(
#selector(self.getHintsFromTextField),
with: textField,
afterDelay: 0.5)
return true
}
@objc func getHintsFromTextField(textField: UITextField) {
print("Hints for textField: \(textField)")
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With