Using same UITextFieldDelegate methods in custom UIView and in UIViewController simultaneously - ios

I have an UIView (named HCTextFieldView) with subviews: UITextField and UILabel above.
UITextField's delegate is equal to self. Delegate methods textFieldDidBeginEditing and textFieldDidEndEditing perform textfield's background highlight effect.
Next I'am using this custom UIView (HCTextFieldView) in my UIViewController. To handle action of 'Next' and 'Previous' buttons in toolbar (attached above textfield's keyboard) I need the same textfield's delegate methods in UIViewController, BUT delegates became overridden.
**#interface HCBaseTextField : UIView <UITextFieldDelegate>**
...
#end
**#implementation HCBaseTextField {}**
...
textField = [[UITextField alloc] initWithFrame:CGRectMake(0, titleLabel.bottom, self.width - 20, self.height - titleLabel.height)];
**textField.delegate = self**;
...
#pragma mark - UITextField delegate
//textFieldBG - UIImageView that act as background
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[textFieldBg setImage:[[UIImage imageWithName:#"btn_vvod_medium_act"] stretchableImageWithLeftCapWidth:10 topCapHeight:10]];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[textFieldBg setImage:[[UIImage imageWithName:#"btn_vvod_medium_norm"] stretchableImageWithLeftCapWidth:10 topCapHeight:10]];
return YES;
}
...
#end
**ViewController : UIViewController**
...
HCTextFieldView *textFieldView = [[HCTExtFieldView alloc] init];
textFieldView.textField.delegate = self;
...
//I need to use this methods too but they override previous in UIView delegate
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self.keyboardControls setActiveField:textField];
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[self.keyboardControls setActiveField:textView];
}

Set a delegate in HCBaseTextField like
in HCBaseTextField.h add a property
#property (nonatomic, assign) id<UITextFieldDelegate> textFieldDelagate;
and in HCBaseTextField.m
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
....
if (self.textFieldDelagate && [self.textFieldDelagate respondsToSelector:#selector(textFieldShouldBeginEditing:)]) {
[self.textFieldDelagate textFieldShouldBeginEditing:textField];
}
return YES;
}
- (void) textFieldDidBeginEditing:(UITextField *)textField {
....
if (self.textFieldDelagate && [self.textFieldDelagate respondsToSelector:#selector(textFieldDidBeginEditing:)]) {
[self.textFieldDelagate textFieldDidBeginEditing:textField];
}
}
... //Other delegate methods if needed
and in ViewController : UIViewController
...
HCTextFieldView *textFieldView = [[HCTExtFieldView alloc] init];
textFieldView.textFieldDelagate = self;
...
and implement delegate methods.
- (void) textFieldDidBeginEditing:(UITextField *)textField {
....
//Do the stuff
}

Related

Subclass tool bar

I added a toolbar on top of the keyboard, it appears every-time the user clicks on a TextView, it also has a number of buttons that change and interact with the TextView, like for example, changing the text font.
What I'm trying to do now is to create a subclass of the Toolbar so that it can be used on other TextViews, but my problem is:
How to use the TextView delegate methods from inside the Toolbar subclass?
Here is my current code(not all code, for not making the post too big):
.h
#import <UIKit/UIKit.h>
#interface CustomUIToolbar : UIToolbar{
UIButton *btn1;
UIButton *btn2;
UIButton *btn3;
}
.m
#implementation CustomUIToolbar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIBarButtonItem *one = ...
UIBarButtonItem *two = ...
UIBarButtonItem *three = ...
self.barStyle = UIBarStyleDefault;
self.layer.borderWidth = 1;
self.layer.borderColor = [[UIColor lightGrayColor] CGColor];
self.items = [NSArray arrayWithObjects:one,placeholder,two,three,four,five,nil];
[self sizeToFit];
}
return self;
}
-(void)actionBtn3:(UIButton *) barBtnItem{
...
}
-(void)actionBtn2:(UIButton *) barBtnItem{
...
}
-(void)actionBtn1:(UIButton *) barBtnItem{
...
}
// And the UITextView Delegate Methods
- (BOOL) textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
...
return YES;
}
- (void)textViewDidChangeSelection:(UITextView *)textView {
...
}
Your CustomUIToolbar class should conform to UITextViewDelegate protocol:
#interface CustomUIToolbar : UIToolbar <UITextViewDelegate> {
Then you need to assign your CustomUIToolbar subclass as a delegate to textView:
self.textView.delegate = self.customTabbar;
Update:
I think the problem because your toolbar instance is released before the delegate method is called on it. Try to make a property to make sure that variable stays in memory. So instead of:
UIToolbar *tool = [[CustomUIToolbar alloc] init];
Create a property:
#property(nonatomic, strong) CustomUIToolbar *tool;
And initialize it:
self.tool = [[CustomUIToolbar alloc] init];
You can make another class for UIextView and import toolbar class in it and call bar button click method from this class. and use textview of this class where it need.

UIGestureRecognizerDelegate implemenation doesn't work

I've tried to implement the UIGestureRecognizerDelegate in my ViewController and somehow the methods aren't called. This is the controller:
#import "DiaryEntryViewController.h"
#import "UINavigationController+BarManagement.h"
#interface DiaryEntryViewController ()<UIGestureRecognizerDelegate>
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (weak, nonatomic) IBOutlet UITextView *textView;
#end
#implementation DiaryEntryViewController
-(void)viewWillAppear:(BOOL)inAnimated{
[super viewWillAppear:inAnimated];
self.navigationController.barsHidden = NO;
}
-(void)viewDidAppear:(BOOL)inAnimated{
[super viewDidAppear:inAnimated];
[self.navigationController hideBarsWithDelay:2.0];
}
-(void)viewWillDisappear:(BOOL)inAnimated{
[self.navigationController setBarsHidden:NO animated:YES];
[super viewWillDisappear:inAnimated];
}
-(NSManagedObjectContext *)managedObjectContext{
return self.diaryEntry.managedObjectContext;
}
-(BOOL)saveDiaryEntry{
BOOL theResult = NO;
NSError *theError = nil;
theResult = [self.managedObjectContext save:&theError];
if(!theResult){
NSLog(#"saveItem %#", theError);
}
return theResult;
}
-(CGRect)visibleBounds{
CGRect theBounds = self.view.bounds;
if([self respondsToSelector:#selector(topLayoutGuide)] && [self respondsToSelector:#selector(bottomLayoutGuide)]){
theBounds.origin.y = [self.topLayoutGuide length];
theBounds.size.height -= [self.topLayoutGuide length] + [self.bottomLayoutGuide length];
}
return theBounds;
}
-(IBAction)toogleBars:(id)sender{
NSLog(#"toogleBars");
UINavigationController *theController = self.navigationController;
BOOL theHiddenFlag = theController.barsHidden;
[theController setBarsHidden:!theHiddenFlag animated:YES];
if(theHiddenFlag){
[theController hideBarsWithDelay:2.0];
}
}
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)inRecognizer{
NSLog(#"gestureRecognizerShouldBegin");
UIView *theView = self.textView;
CGPoint thePoint = [inRecognizer locationInView:theView];
return !CGRectContainsPoint(theView.bounds, thePoint);
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
NSLog(#"bla");
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
NSLog(#"ble");
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
NSLog(#"blä");
return YES;
}
#end
It does call toogleBars methods, but none of the recognizer methods.
Do not forget to declare and add the recognizer to the view you want to detect that tap or swipe in
example:
Add a property like "theTapRecognizer" to the VC.
Alloc and init that recognizer:
self.theTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: self action: #selector(someMethod:)];
self.theTapRecognizer.delegate = self;
[someView addGestureRecognizer: selftheTapRecognizer];
someView is the placeholder text to the view you want to init that recognizer in, it can be the whole self.view or some subview,
you can listen for any interaction with that gesture recognizer with the following delegate method
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
Assuming you have added the UIGestureRecognizer from the storyboard, you need to remember to CTRL + Drag the gesture object to the UIViewController yellow circle image and set the delegate.
Your UIGestureRecognizer object will be on the top of the UIViewController view. CTL Drag this to the yellow circle ViewController icon
Then this pop-up will show and select 'Delegate' so that the gesutureRecognizer will use the delegate methods.

UIKeyboard behind Picker View

I have Two text field in my View. i am using picker view as input. when ever picker is enabled the keyboard is visible behind the picker.The other issue is when i use Resign First responder for the text field in the Action the first time it shows picker without the keyboard at behind.But the second time when i click the text field the KeyBoard appears instead of picker. Here is my code.
- (IBAction)selectService:(id)sender
{
[self createActionSheet];
//[selectServiceTextBox resignFirstResponder];
pickerType = #"servicePickerType";
servicePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 44.0, 0.0, 0.0)];
pickerArray = [[NSArray alloc]initWithObjects:#"Money Transfer",#"Bill Payment", nil];
servicePicker.dataSource = self;
servicePicker.delegate = self;
servicePicker.showsSelectionIndicator = YES;
[actionSheet addSubview:servicePicker];
// rowIndex = [stateTextField.text intValue];
//[servicePicker selectRow:rowIndex inComponent:0 animated:NO];
}
- (IBAction)wayOfTransfer:(id)sender
{
if ([selectedItem isEqualToString:#""])
{
NSLog(#"empty selection");
}
else if ([selectServiceTextBox.text isEqualToString:#"Money Transfer"])
{
[self createActionSheet];
// [secondTextBox resignFirstResponder];
//[selectServiceTextBox resignFirstResponder];
pickerType = #"MoneyTransferMethod";
servicePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 44.0, 0.0, 0.0)];
pickerArrayTwo = [[NSArray alloc]initWithObjects:#"Cash Pick-up",#"Bank Account",#"Zym Card", nil];
servicePicker.dataSource = self;
servicePicker.delegate = self;
servicePicker.showsSelectionIndicator = YES;
[actionSheet addSubview:servicePicker];
}
}
You have to make the picker and keyboard appear exclusive of each other so that both can gracefully be switched between each other.. One way to do it is make the picker hidden by default and then bring it on screen when the first textview is on focus using an animation... Similarly hide it while bringing keyboard on using the second textview.
I have made a sample project that does this and have tested it... I hope this is what you intend to do...
//ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITextViewDelegate,UIPickerViewDataSource,UIPickerViewDelegate>
#property (weak, nonatomic) IBOutlet UITextView *firstTextView;
#property (weak, nonatomic) IBOutlet UITextView *secondTextView;
#property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
#end
//ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController{
NSMutableArray *pickerDataSource;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
pickerDataSource = [[NSMutableArray alloc] initWithObjects:#"data1",#"data2", nil];
self.pickerView.frame = CGRectMake(0, self.view.frame.size.height, 320, 162);
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
}
// Textview delegates
-(void)textViewDidBeginEditing:(UITextView *)textView{
if ([textView isEqual:self.firstTextView]) {
[textView resignFirstResponder];
if (self.pickerView.frame.origin.y >= self.view.frame.size.height) {
[self showPicker];
}else{
[self hidePicker];
}
}else{
[self hidePicker];
[self.secondTextView becomeFirstResponder];
}
}
-(void)showPicker{
[UIView animateWithDuration:0.2 animations:^{
self.pickerView.frame = CGRectMake(self.pickerView.frame.origin.x, self.pickerView.frame.origin.y - self.pickerView.frame.size.height, self.pickerView.frame.size.width, self.pickerView.frame.size.height);
}];
}
-(void)hidePicker{
[UIView animateWithDuration:0.2 animations:^{
self.pickerView.frame = CGRectMake(self.pickerView.frame.origin.x, self.pickerView.frame.origin.y + self.pickerView.frame.size.height, self.pickerView.frame.size.width, self.pickerView.frame.size.height);
}];
}
// Picker Delegates
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return pickerDataSource.count;
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
self.firstTextView.text = pickerDataSource[row];
}
-(NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [pickerDataSource objectAtIndex:row];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Please let me know if there is anything unclear.
i think you need hide keyboard behind picker view ... simple you put this code in your text click action method
UItextfield delegate method.....
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[text_box_variable resignFirstResponder];
}

How to dismiss keyboard iOS programmatically when pressing return

I created a UITextField programmatically making the UITextField a property of the viewController. I need to dismiss the keyboard with the return and the touch on the screen. I was able to get the screen touch to dismiss, but pressing return is not working.
I've seen how to do it with storyboards and by allocating and initializing the UITextField object directly without creating it as a property. Possible to do?
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (strong, atomic) UITextField *username;
#end
.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor blueColor];
self.username = [[UITextField alloc] initWithFrame:CGRectMake(100, 25, 80, 20)];
self.username.placeholder = #"Enter your username";
self.username.backgroundColor = [UIColor whiteColor];
self.username.borderStyle = UITextBorderStyleRoundedRect;
if (self.username.placeholder != nil) {
self.username.clearsOnBeginEditing = NO;
}
_username.delegate = self;
[self.view addSubview:self.username];
[_username resignFirstResponder];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"touchesBegan:withEvent:");
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}
#end
The simple way is to connect the delegate of UITextField to self (self.mytestField.delegate = self) and dismiss the keyboard in the method textFieldShouldReturn using [textField resignFirstResponder];
Another way to dismiss the keyboard is the following:
Objective-C
[self.view endEditing:YES];
Swift:
self.view.endEditing(true)
Put [self.view endEditing:YES]; where you would like to dismiss the keyboard (Button event, Touch event, etc.).
Add a delegate method of UITextField like this:
#interface MyController : UIViewController <UITextFieldDelegate>
And set your textField.delegate = self; then also add two delegate methods of UITextField
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return YES;
}
// It is important for you to hide the keyboard
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
simply use this in swift to dismiss keyboard:
UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)
Swift 3
UIApplication.shared.sendAction(#selector(UIResponder.resign‌​FirstResponder), to: nil, from: nil, for: nil)
//Hide keyBoard by touching background in view
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[[self view] endEditing:YES];
}
SWIFT 4:
self.view.endEditing(true)
or
Set text field's delegate to current viewcontroller and then:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
Objective-C:
[self.view endEditing:YES];
or
Set text field's delegate to current viewcontroller and then:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
In the App Delegate, you can write
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.window endEditing:YES];
}
use this way, you can don`t write too much code.
Try to get an idea about what a first responder is in iOS view hierarchy. When your textfield becomes active(or first responder) when you touch inside it (or pass it the messasge becomeFirstResponder programmatically), it presents the keyboard. So to remove your textfield from being the first responder, you should pass the message resignFirstResponder to it there.
[textField resignFirstResponder];
And to hide the keyboard on its return button, you should implement its delegate method textFieldShouldReturn: and pass the resignFirstResponder message.
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Here's what I use in my code. It works like a charm!
In yourviewcontroller.h add:
#property (nonatomic) UITapGestureRecognizer *tapRecognizer;
Now in the .m file, add this to your ViewDidLoad function:
- (void)viewDidLoad {
[super viewDidLoad];
//Keyboard stuff
tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapRecognizer];
}
Also, add this function in the .m file:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
For a group of UITextViews inside a ViewController:
Swift 3.0
for view in view.subviews {
if view is UITextField {
view.resignFirstResponder()
}
}
Objective-C
// hide keyboard before dismiss
for (UIView *view in [self.view subviews]) {
if ([view isKindOfClass:[UITextField class]]) {
// no need to cast
[view resignFirstResponder];
}
}
To dismiss a keyboard after the keyboard has popped up, there are 2 cases,
when the UITextField is inside a UIScrollView
when the UITextField is outside a UIScrollView
2.when the UITextField is outside a UIScrollView
override the method in your UIViewController subclass
you must also add delegate for all UITextView
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
In a scroll view, Tapping outside will not fire any event, so in that case use a Tap Gesture Recognizer,
Drag and drop a UITapGesture for the scroll view and create an IBAction for it.
to create a IBAction, press ctrl+ click the UITapGesture and drag it to the .h file of viewcontroller.
Here I have named tappedEvent as my action name
- (IBAction)tappedEvent:(id)sender {
[self.view endEditing:YES]; }
the abouve given Information was derived from the following link, please refer for more information or contact me if you dont understand the abouve data.
http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/
I know this have been answered by others, but i found the another article that covered also for no background event - tableview or scrollview.
http://samwize.com/2014/03/27/dismiss-keyboard-when-tap-outside-a-uitextfield-slash-uitextview/
Since the tags only say iOS i will post the answer for Swift 1.2 and iOs 8.4, add these in your view controller swift class:
// MARK: - Close keyboard when touching somewhere else
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
// MARK: - Close keyboard when return pressed
func textFieldShouldReturn(textField: UITextField!) -> Bool {
textField.resignFirstResponder()
return true
}
// MARK: -
Also do not forget to add UITextFieldDelegate in the class declaration and set your text fields delegate to self (the view).
IN Swift 3
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
OR
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == yourtextfieldName
{
self.resignFirstResponder()
self.view.endEditing(true)
}
}
First you need to add textfield delegete in .h file. if not declare
(BOOL)textFieldShouldReturn:(UITextField *)textField this method not called.so first add delegate and write keyboard hide code into that method.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
try this one..
So here's what I did to make it dismiss after touching the background or return. I had to add the delegate = self in viewDidLoad and then also the delegate methods later in the .m files.
.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (strong, atomic) UITextField *username;
#end
.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor blueColor];
self.username = [[UITextField alloc] initWithFrame:CGRectMake(100, 25, 80, 20)];
self.username.placeholder = #"Enter your username";
self.username.backgroundColor = [UIColor whiteColor];
self.username.borderStyle = UITextBorderStyleRoundedRect;
if (self.username.placeholder != nil) {
self.username.clearsOnBeginEditing = NO;
}
self.username.delegate = self;
[self.username resignFirstResponder];
[self.view addSubview:self.username];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#end
Simply use this in Objective-C to dismiss keyboard:
[[UIApplication sharedApplication].keyWindow endEditing:YES];
Add Delegate : UITextFieldDelegate
#interface ViewController : UIViewController <UITextFieldDelegate>
and then add this delegate method
// This should work perfectly
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view.subviews enumerateObjectsUsingBlock:^(UIView* obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UITextField class]]) {
[obj resignFirstResponder];
}
}];
}
when you using more then one textfield in screen
With this method you doesn't need to mention textfield every time like
[textField1 resignFirstResponder];
[textField2 resignFirstResponder];
Swift 2 :
this is what is did to do every thing !
close keyboard with Done button or Touch outSide ,Next for go to next input.
First Change TextFiled Return Key To Next in StoryBoard.
override func viewDidLoad() {
txtBillIdentifier.delegate = self
txtBillIdentifier.tag = 1
txtPayIdentifier.delegate = self
txtPayIdentifier.tag = 2
let tap = UITapGestureRecognizer(target: self, action: "onTouchGesture")
self.view.addGestureRecognizer(tap)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
if(textField.returnKeyType == UIReturnKeyType.Default) {
if let next = textField.superview?.viewWithTag(textField.tag+1) as? UITextField {
next.becomeFirstResponder()
return false
}
}
textField.resignFirstResponder()
return false
}
func onTouchGesture(){
self.view.endEditing(true)
}
If you don't know current view controller or textview you can use the Responder Chain:
UIApplication.shared.sendAction(#selector(UIView.endEditing(_:)), to:nil, from:nil, for:nil)
for swift 3-4 i fixed like
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return false
}
just copy paste anywhere on the class. This solution just work if you want all UItextfield work as same, or if you have just one!

is there some API of ios that can display keyboard manually

I have a custom view, i want display a keyboard as my input and intercommunicate with it.
thanks guys~
In your custom view you must add a zero-sized UITextField and then set your view as its delegate. Then in your custom view define a gesture recognizer (e.g. a single tap) and in the gesture recognizer recognition event set the text field as first responder.
As soon as you tap the view the keyboard will popup. Then write the delegate method:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
to manage the interaction with the typed string. Don't forget to call setNeedsDisplay if you need to update your view on the user keyboard typing.
The example below works. You must instantiate the custom view in your view controller of course. With the example, just type a letter in the keyboard and it will be displayed on the view.
//
// MyView.h
//
#import
#interface MyView : UIView {
UITextField *tf;
}
#property (nonatomic,copy) NSString *typed;
#end
//
// MyView.m
//
#import "MyView.h"
#implementation MyView
#synthesize typed;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor=[UIColor redColor];
tf = [[UITextField alloc] initWithFrame:CGRectZero];
tf.delegate=self;
[self addSubview:tf];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
[self addGestureRecognizer:tap];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
- (void)drawRect:(CGRect)rect
{
// Draw the "typed" string in the view
[[UIColor blackColor] setStroke];
if(self.typed) {
[self.typed drawAtPoint:CGPointZero withFont:[UIFont systemFontOfSize:50]];
}
}
-(void)tap:(UIGestureRecognizer *)rec {
if(rec.state==UIGestureRecognizerStateEnded) {
[tf becomeFirstResponder];
}
}
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
self.typed=[string substringToIndex:1]; // extract the first character of the string
[self setNeedsDisplay]; // force view redraw
}
#end
I think the solution could be as simple as implementing the UIKeyInput protocol in your class.
Read more about the UIKeyInput Protocol Reference.

Resources