I am using custom cell with XIB. Now I scroll the table so the cell having the textFiled will be invisible. In this condition if i return the textField (means I call the [textField resignFirstResponder]) The app will crash and giving the error like
[UITableViewCell _didChangeToFirstResponder:]: message sent to deallocated instance
0xe05aa20.
Please let me know if you have any idea about this.
You should check couple of things:
1) In cellForRowAtIndexPath delegate, when you use dequeueReusableCellWithIdentifier you should set endEditing to YES for this view something like:
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"identifier"];
[cell setEndEditing:YES];
if(!cell)
{
// Rest of the logic goes here
}
2) Don't forget to set UITableViewDelegate to self which should represent a live class. So when delegate function calls, class exists.
You need to check whether your TextField is first responder. If it was then you can resign it safely
Hide Keyboard for myTextField
if ([myTextField isFirstResponder]) {
[myTextField resignFirstResponder];
}
To resign First Responder for any subview in a view
for (UIView *aSubView in self.view.subviews) {
if ([aSubView isFirstResponder]) {
[aSubView resignFirstResponder];
//break;
}
}
Use Following method to resolve issue of resignFirstResponder :
[self resignFirstResonder:self.view];
- (BOOL)resignFirstResonder:(UIView *)textView
{
keyBoardShow = NO;
if(badgeHasFullInfo == YES)
{
if (textView.isFirstResponder)
{
[textView resignFirstResponder];
return YES;
}
for (UIView *subView in textView.subviews)
{
if ([self findAndResignFirstResonder:subView])
{
return YES;
}
}
}
return NO;
}
Related
I have a UITableViewController with custom UITableViewCell. Where each cell contains a UITextField. Now what i want is to shift the control from one text field to the every next text field when return key is pressed.
what i m thinging to do is this...
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSIndexPath *currentIndexPath=[self.tableView indexPathForCell:(UITableViewCell*)textField.superview.superview];
if(currentIndexPath.row<_excerciseData.totalBlanks-1){
NSIndexPath nextIndexPath=???
UITextField *nextTextFeild=[(UITableViewCell*)[self.tableView cellForRowAtIndexPath:nextIndexPath] viewWithTag:2];
[nextTextFeild becomeFirstResponder];
}else{
[textField resignFirstResponder];
}
return YES;
}
but for this i don't know, how to find the indexPath of very next UITableViewCell. Can anybody help me to find this? this... :)
Since you already have a custom table view cell the simplest solution would be to add a property that holds the index path. Then in the delegate method where you return the cell simply assign the current index path to the cell which may later be used.
This will not work very well for the last cell in the section or the table view itself. What you should do is report the event to the table view owner (the view controller) from the cell itself which may then compute what the next cell index is: If you have multiple sections it must check if it should go to a new section and if it is the last cell simply do nothing (or go to the beginning of the table view if you wish).
For forwarding messages you may try one of the procedures mentioned in the answer here: IOS: Navigate through tableView and show table view data on next view
Just to be clear, the text field delegate should be the cell itself!
Better you can do like this,
CGPoint pointInTable = [field convertPoint:field.bounds.origin toView:_tableView];
NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:pointInTable];
Reference : How to get a UITableViewCell from one of its subviews
or do like this,
id view = [textfield superview];
while (view && [view isKindOfClass:[UITableViewCell class]] == NO) {
view = [view superview];
}
UITableViewCell *tableViewCell = (UITableViewCell *)view;
Reference : How to get UITableView from UITableViewCell?
Better way you can use tag property of textField. Do like this.
While you creating cell with cellForRowAtIndexPath
give a tag value for textField inside the cell like:
cell.yourTextField.tag = indexPath.row + someConstant; // someConstant is just to make sure that there is no textfield with the same tag value
and in your textField delegate: - (BOOL)textFieldShouldReturn:(UITextField *)textField implement the following.
// Jumping with the keyboard Next button implementation.
if (UIReturnKeyNext == textField.returnKeyType) //may be u can avoid this check
{
id nextField = [self viewWithTag:textField.tag + 1];
if ([nextField isKindOfClass:[UITextField class]])
{
[nextField becomeFirstResponder];
}
}
Hopes the textFieldDelegates are implemented in the tableview's owner class.
Solution here
#prgma mark - UITableViewDelegate Methods
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *stringCell = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.yourTextField.tag = indexPath.row;
return cell;
}
#prgma mark - UITextFieldDelegate Methods
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSUInteger index = textField.tag;
UITextField *nextTextField = (UITextField*)[self.view viewWithTag:index+1];
[nextTextField becomeFirstResponder];
return YES;
}
In my iPad application i have few UITableView on same view created programmatically. They must pretend one multicolumn table. Each cell contains UITextField. It's size is equal to cell's size (its the reason why i cant get UITableView's delegate methods didSelect/didDeselect row). My problem is when i begin edit one text field then try to remove focus to other textfield it needs two taps. After first tap no one of cell is not editing. Such behavior observing only inside same table. If i want to change focus to other table its possible in one tap. What i missed?
Here is my UITextField Delegate methods in Cell's class
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if ([_delegate checkForAccess:self]) {
if (!((CTKTextField *)textField).isEditable)
{
[_delegate callPickerUnderCell:self];
return NO;
}
else
{
[_delegate getPosition:self];
return YES;
}
}
else return NO;
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if (_textField.text.length == -1)
{
_textField.rightView = nil;
}
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSString *input = textField.text;
[_delegate saveEdit:self withText:input];
}
If textFieldShouldBeginEditing is called after first tap and you return YES then text field starts editing. Probably you are making endEditing to the whole tableView after that.
If you call endEditing on the specific cell in your cell's delegate instead of the whole table view it should work.
That might be caused by autocapitalizationType. Your have to dismiss the auto correction before getting your textField becomeFirstResponder. Disable it will solve the problem.
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
Edit:
I was confused, try this one:
textField.autocorrectionType = UITextAutocorrectionTypeNo;
Try to set UITableViewCellSelectionStyleNone to your table view cells with text fields.
I have made a simple program where you can add "cells" with UITextFields (ergo they are editable) with the help of a 'add Button' in the "edit mode" of a TableView.
When pressing the return key I want that the program 'jumps out' of the editing mode to the 'normal' Table View.
I guess you setup the user interface for your app in a xib or storyboard? So, make sure you connect the delegate outlet of the UITextField to your (view) controller and implement the delegate method textFieldShouldReturn: there:
- (BOOL)textFieldShouldReturn:(UITextField*)textField;
{
[textField resignFirstResponder];
return NO;
}
You can end the editing in the table view by using the method setEditing:animated:
[self.tableView setEditing:No animated:YES];
You would do it inside the textField delegate method.
- (BOOL)textFieldShouldReturn:(UITextField*)textField;
{
[textField resignFirstResponder];
if(self.tableview.editing){
[self.tableView setEditing:NO animated:YES];
}
return NO;
}
You have setEditing:animated: method and editing property on UIViewController itself. So, you could do it from those properties as well like;
- (BOOL)textFieldShouldReturn:(UITextField*)textField;
{
[textField resignFirstResponder];
if(self.editing){
[self setEditing:NO animated:YES];
}
return NO;
}
I'm trying to have the advantage of the UITextView with Data Detector Types inside a TableViewCell that is itself clickable.
The only thing is, I need the UITextView's links to be clickable, so userInteractionEnabled = YES, unfortunately this will prevent any touch going through to the UITableViewCell.
Of course the UITextView can't be edited, I also subclassed it refusing it to be first responder to avoid selecting text in it.
The only thing I need, is detecting that if a user touch the UITextView, check if it was a link, if it is then opening the link, otherwise redirect the touch on the UITableViewCell.
any idea how can this be done ?
much like the twitter App (we can either click on the row, or on the link...)
I know that this question has been asked a while ago, but the behaviour is still very much needed for some app to have a clickable Cell with UIDataDetectors.
So here's the UITextView subclass I made up to fit this particular behaviour in a UITableView
-(id) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.delegate = self;
}
return self;
}
- (BOOL)canBecomeFirstResponder {
return NO;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UIView *obj = self;
do {
obj = obj.superview;
} while (![obj isKindOfClass:[UITableViewCell class]]);
UITableViewCell *cell = (UITableViewCell*)obj;
do {
obj = obj.superview;
} while (![obj isKindOfClass:[UITableView class]]);
UITableView *tableView = (UITableView*)obj;
NSIndexPath *indePath = [tableView indexPathForCell:cell];
[[tableView delegate] tableView:tableView didSelectRowAtIndexPath:indePath];
}
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange {
return YES;
}
You can modify this to fit your needs...
Hope it helps someone.
I added textfield to tableview cell contentview.when i'm editing any textfield and i scrolled the tableview to bottom and dismiss the keyboard Then app crashed ,because of this reason [UITableViewCell _didChangeToFirstResponder:]: message sent to deallocated instance
Try to hide the keyboard while scrolling.
In h class
Declare a textfield
UITextField *selectedTextField;
In m class
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
selectedTextField = textField;
return YES;
}
I also had the same problem. The above solution fixed it.
All the best.
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[selectedTextField resignFirstResponder];
}