I have this code, who capture when the user click in my textfield, and call a function:
-(void)viewDidLoad{
[mytextfield addTarget:self
action:#selector(callvariant:)
forControlEvents:UIControlEventTouchDown];
}
-(void)callvariant:(UITextField *)textField{
NovoProdutoMFViewController *mf = [[NovoProdutoMFViewController alloc] init];
[self.navigationController pushViewController:mf animated:YES];
[mf setBusca:textField.placeholder];
}
The code works perfectly, but recently had the need to put a UIScrollView in my project with this code:
-(void)viewDidLoad{
[mytextfield addTarget:self
action:#selector(callvariant:)
forControlEvents:UIControlEventTouchDown];
scroll.contentSize = scroll.frame.size;
scroll.frame = self.view.frame;
[self.view addSubview:scroll];
}
-(void)callvariant:(UITextField *)textField{
NovoProdutoMFViewController *mf = [[NovoProdutoMFViewController alloc] init];
[self.navigationController pushViewController:mf animated:YES];
[mf setBusca:textField.placeholder];
}
Now Sometimes when the user click on textfield call the function and sometimes not call, and at other times it is necessary to keep the text field clicked down for more than 2 seconds to call the function and has sometimes this method does not work.
I do not know what might be happening, but how can I solve this?
If you want to catch the event of user touch a UITextField, You better use its delegate method.
UITextFieldDelegat has a method
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; // return NO to disallow editing.
if you do something here and return NO, you will get the same result.
Related
I have a UITextView that is created programmatically on viewDidLoad using the method below. Keyboard is shown successfully right after [_answerTextView becomeFirstResponder] is called. And hid if the user enters return(\n) character.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:#"\n"]) {
[self endEditing:YES];
return NO;
}
return YES;
}
After the keyboard is hid by the code above, I'm not able to bring it back anymore by tapping the UITextView again.
I tried showing the keyboard by calling [_answerTextView becomeFirstResponder] on Tap event for the parent UIView and it worked. But that's not what I want.
UITextView is created by the method below;
-(UITextView*)createSurveyTextView{
_answerTextView = [[UITextView alloc]initWithFrame:CGRectMake(0, 0, _optionsStackView.frame.size.width, 200)];
_answerTextView.keyboardType = UIKeyboardTypeDefault;
_answerTextView.text = #"";
_answerTextView.editable = true;
_answerTextView.selectable = true;
_answerTextView.delegate = self;
[_answerTextView becomeFirstResponder];
_answerTextView.backgroundColor = [UIColor whiteColor];
_answerTextView.textColor = [UIColor blackColor];
_answerTextView.layer.cornerRadius = 5;
[_optionsStackView addSubview:_answerTextView];
_answerTextView.font = [UIFont systemFontOfSize:20];
[_answerTextView setReturnKeyType:UIReturnKeyDone];
[_optionsStackView bringSubviewToFront:_answerTextView];
[self bringSubviewToFront:_answerTextView];
[_answerTextView setUserInteractionEnabled:true];
UITapGestureRecognizer *mainViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTextViewTap:)];
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap2:)];
[_answerTextView addGestureRecognizer:mainViewTap];
[self addGestureRecognizer:tap2];
return _answerTextView;
}
I want the UITextView to simply show the keyboard when the user taps on it self. What am I missing?
Edit: I have the same sources in another view, but everything works fine there. The only difference is, here the UITextView is created programmatically.
Edit 2: I got it worked. The _optionsStackView that the UITextView is added as a child is a UIStackView. I tried adding the _answerTextView to the parent UIView and everything works fine now. What would be the problem with the UIStackView?
Your problem very strange in your code.You can explantion why use UITapGestureRecognizer to this UITextView control.How do you think this lead to conflict?
I find your problem where in start,but I create new project to ensure.So I confirm that UITextView already has target with itself.Also you can't to add UITapGestureRecognizer.
What you're doing is almost correct, but just try changing endEditing: to [textView resignFirstResponder]:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if ([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
If that doesn't work, then it could be that one of your gestures is preventing the UITextView's own UITapGestureRecognizer from receiving the tap. Try disabling (or comment out the creation of) both of your recognizers to verify that it is the issue. If it is, then you can fix it using the UIGestureRecognizerDelegate methods.
You did not use common way to hide/close the keyboard.
Try this common way:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
return [textField resignFirstResponder];
}
This is a method in the UITextFieldDelegate, use it and remove your code:
if([text isEqualToString:#"\n"]) {
[self endEditing:YES];
return NO;
}
Edit:
#siburb You are right. My bad.
UITapGestureRecognizer maybe the root cause.
Edit:
#Semih Akbas
Repalce:
[_optionsStackView addSubview:_answerTextView];
To:
[_optionsStackView addArrangedSubview:_answerTextView];
I'm not sure it can be able to add DatePicker dynamically under UITextField when tapped on. If possible, help me to show sample code for that.
on click event set on text field
- (void)viewDidLoad {
[super viewDidLoad];
[textField addTarget:self action:#selector(clicked:) forControlEvents:UIControlEventEditingDidBegin];
}
set text field edition false
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
return NO;
}
Method when clickd on text filed
-(IBAction)clicked:(id)sender
{
[sender resignFirstResponder];
picker1 = [[UIDatePicker alloc] initWithFrame:CGRectMake(textField.frame.origin.x-40, textField.frame.origin.y+textField.frame.size.height, textField.frame.size.width, 200)];
[picker1 setDatePickerMode:UIDatePickerModeDate];
picker1.backgroundColor = [UIColor whiteColor];
[picker1 addTarget:self action:#selector(startDateSelected:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:picker1];
}
when date value changed this method is called
-(IBAction)startDateSelected:(id)sender
{
NSLog(#"%#",picker1.date);
[textField setText:[NSString stringWithFormat:#"%#",picker1.date
]];
}
I hope it will help you! :)
I want to show UITableView on tapping of UITextView.
key board should not be shown.
the problem is on tapping UITextView both UITableView and keyboard are shown.
I want only table view to be shown. I want to display data got from web service in UITextView which is not editable.on pressing edit button in navigation bar that time on tapping UITextView ,UITableView should be popped up and not keyboard.
My code is below:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
if([text isEqualToString:#"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
-(void)textViewDidBeginEditing:(UITextView *)textView{
[self.view endEditing:YES];
tableVw=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 500)];
tableVw.dataSource=self;
tableVw.delegate=self;
[self.view addSubview:tableVw];
}
-(void)viewDidLoad{
[super viewDidLoad];
txtVwDescription=[[UITextView alloc]initWithFrame:CGRectMake(10, 270, 300,stringSize.height+10)];
txtVwDescription.backgroundColor=[UIColor clearColor];
txtVwDescription.layer.cornerRadius=5;
txtVwDescription.backgroundColor=[UIColor colorWithRed:0.662745 green:0.662745 blue:0.662745 alpha:0.3];
[txtVwDescription setFont:[UIFont systemFontOfSize:13.0]];
txtVwDescription.contentInset=UIEdgeInsetsMake(0, 0, 0, 0);
[txtVwDescription setUserInteractionEnabled:NO];
txtVwDescription.editable=NO;
txtVwDescription.delegate=self;
[self.view addSubview:txtVwDescription];
}
-(void)edit{
[txtVwDescription setUserInteractionEnabled:YES];
txtVwDescription.editable=NO;
[txtVwDescription resignFirstResponder];
}
you can use UITextViewDelegate's textViewShouldBeginEditing method returning NO, and presenting there the UITableView. In such a way the keyboard should not be presented.
Rather than having to mess with textViewDelegate methods, I find it easier to simply disable editing for the textView and add a gesture recognizer to it like this:
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showTableView)];
UITextView *textView = [[UITextView alloc] initWithFrame:....];
textView.editable = NO;
[textView addGestureRecognizer:tapGestureRecognizer];
This way, no keyboard is shown and you don't have to mess around with navigation inside the delegate methods. All you need to do now is handle the tap with the method you provided the recognizer:
- (void)showTableView {
// do stuff here
}
EDIT:
You might want to also consider using a UILabel instead of a UITextView if you are not planning on making it editable at all. You can implement the same gesture recognizer code as well, just add it to the label instead of the textView.
UITextField and UITextView classes has a property named inputView for displaying custom views instead of the default keyboards. The system shows whatever UIView descendant class you set to that property when the textfield/view becomes first responder. So simply add,
UITextView *textView = [[UITextView alloc] initWithFrame:someFrame];
textView.inputView = self.myTableView; //this is your already initialised tableview
I'm trying to make keypad disappear on tapping the empty area (the textfields are in tableViewCells) I'm able to do that with following code
-(void) initTapGesture{ //calling in viewDidLoad
self.singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onTappingView)];
self.singleTap.numberOfTapsRequired = 1;
self.singleTap.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:self.singleTap];
}
-(void)onTappingView{
[self.tableView endEditing:YES]; // or [self.view endEditing:YES];
}
but after this the tableView cell's didSelectRowAtIndexPath delegate method is not being called at all.What should I do??
I also tried the following code for onTappingView function it didn't work :
-(void)onTappingView{
RegistrationTabelViewCell *cell=(RegistrationTabelViewCell*)[self.registerationTabelView cellForRowAtIndexPath:self.currentCellIndexPath];
[cell.textField resignFirstResponder];
}
I just spent most of a day tracking down a very strange case where calling resignFirstResponder on the active UITextField did not hide the keyboard, even though the textfield was the first responder. This happens when I push a view controller on top of another view controller with an active text field. The keyboard goes away (as expected). But if I bring the keyboard back by touching a textfield in the 2nd view controller, subsequent calls to resignFirstResponder have no effect.
Here's simple code to reproduce the issue. This code is a view controller with a nav bar button to hide the keyboard, and another to push another copy of itself (with a confirmation UIAlertView). The first copy works without problem. However, if you push a 2nd copy (when the first copy has a visible keyboard) it is impossible to dismiss the keyboard. This only happens if there is a UIAlertView (the confirmation) on the screen when the 2nd copy is pushed. If you remove the #define ALERT line, everything works.
Does anyone know what is happening here? It looks like the UIALertView window is somehow interfering with the keyboard and keeping it's window from disappearing, which then confuses the next view. Is there any solution here other than pushing the 2nd view controller on a timer after the UIALertView is gone?
Sorry for the complex description. This is runnable code. I hope that the code is clear.
#implementation DemoViewController
- (id) init {
if (!(self = [super init]))
return nil;
return self;
}
- (void) dealloc {
[_inputTextfield release];
[super dealloc];
}
- (void) loadView {
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
_inputTextfield = [[UITextField alloc] initWithFrame:CGRectMake(0., 0., 320., 44.)];
_inputTextfield.borderStyle = UITextBorderStyleRoundedRect;
_inputTextfield.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
_inputTextfield.keyboardAppearance = UIKeyboardAppearanceAlert;
_inputTextfield.autocapitalizationType = UITextAutocapitalizationTypeNone;
_inputTextfield.autocorrectionType = UITextAutocorrectionTypeNo;
_inputTextfield.keyboardType = UIKeyboardTypeDefault;
[view addSubview:_inputTextfield];
self.view = view;
[view release];
}
- (void) viewWillAppear:(BOOL) animated {
[super viewWillAppear:animated];
UIButton *downButton = [UIButton buttonWithType:UIButtonTypeCustom];
[downButton setTitle: #"keyboard down" forState:UIControlStateNormal];
[downButton addTarget:self action:#selector(downButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[downButton sizeToFit];
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:downButton] autorelease];
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeCustom];
[nextButton setTitle: #"next" forState:UIControlStateNormal];
[nextButton addTarget:self action:#selector(nextButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[nextButton sizeToFit];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:nextButton] autorelease];;
}
- (void) viewWillDisappear:(BOOL) animated {
[super viewWillDisappear:animated];
[_inputTextfield resignFirstResponder];
}
- (void) downButtonPressed:(id)sender {
[_inputTextfield resignFirstResponder];
}
#define ALERT
- (void) alertView:(UIAlertView *) alertView didDismissWithButtonIndex:(NSInteger) buttonIndex {
if (alertView.cancelButtonIndex == buttonIndex) {
return;
}
[self _nextButtonPressed];
}
- (void) _nextButtonPressed {
DemoViewController *nextViewController = [[DemoViewController alloc] init];
[self.navigationController pushViewController:nextViewController];
[nextViewController release];
}
- (void) nextButtonPressed:(id)sender {
#ifdef ALERT
UIAlertView *alert = [[UIAlertView alloc] init];
alert.message = #"Next view?";
alert.cancelButtonIndex = [alert addButtonWithTitle:#"No"];
[alert addButtonWithTitle:#"Yes"];
alert.delegate = self;
[alert show];
[alert release];
#else
[self _nextButtonPressed];
#endif
}
If you had bad luck resigning your first responders, here are a few solutions that might help:
Determine who has remained the first responder after your last call to resign first responder.
Try resigning all first responders by a single call to self.view (container view)
[self.view endEditing:YES];
ONLY if you've tried all the above methods and none worked, consider using this workaround.
-(BOOL)textViewShouldEndEditing:(UITextView *)textView {
NSArray *wins = [[UIApplication sharedApplication] windows];
if ([wins count] > 1) {
UIWindow *keyboardWindow = [wins objectAtIndex:1];
keyboardWindow.hidden = YES;
}
return YES;
}