I have a TableView based application where I have incorporated a UISearchBarDelegate. The application works as intended. The tableview is displayed with all data, along with the UISearchBar. When text is entered into the search field, the list is narrowed down to match that of the text entered.
The problem that I am experiencing is that when I click the cancel button, the keyboard disappears as it should but the original array is not returned....It still shows the searched item(s) as they appear.
In my searchBarCancelButtonClicked section, I have the following code:
- (void)searchBarCancelButtonClicked:(UISearchBar *)SearchBar
{
SearchBar.text = nil;
[SearchBar resignFirstResponder];
[tableView reloadData];
}
I would assume that the [tableView reloadData] section should reload the data from the original array when the cancel button is clicked but it does not do that. Any ideas as to what I might be doing wrong here?
Also, here is my cellForRowAtIndexPath. When comparing to other examples, it seems like I am doing things correctly....With nothing obvious sticking out at me.
-(UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyIndentifier"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
StateDetail *cd;
if(isFiltered)
cd = [self.searchStates objectAtIndex:indexPath.row];
else
cd = [self.listOfStates objectAtIndex:indexPath.row];
cell.textLabel.text = cd.stateName;
return cell;
}
Thank you in advance!
I suspect that the problem is in the way you generate your table results. Are you using a temporary (filtered) array to store the data for when the user runs a search? It'd be helpful to see your cellForRowAtIndexPath method, etc.
First suggestion: make sure that all of your tableView delegate methods check for whether or not the user is searching. For example, you can have a BOOL userSearching that you set as appropriate, and then check every time to see if the user is searching. Then, you can pick your cell from the correct array (if you're using two, as I described above).
Second suggestion: use a SearchDisplayController, rather than a standalone searchbar. It handles most of this functionality for you. If you use this strategy, then you can check for whether or not the user is searching in methods like cellForRowAtIndexPath with:
if (tableView == self.searchDisplayController.tableView)... {
//user is searching, so act appropriately
} else {
//user is not searching...
}
(Here, tableView is the local variable passed into the method. I'm writing that code from memory, so apologies for any errors.)
Let me know if you need any more clarification on either of these strategies.
Try this::
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
isSearching = YES;
self.searchBar.showsCancelButton = YES;
for (UIView *subView in searchBar.subviews) {
if ([subView isKindOfClass:[UIButton class]]) {
UIButton *cancelButton = (UIButton*)subView;
[cancelButton setTitle:#"hi" forState:UIControlStateNormal];
}
}
self.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
UITextField *textField = [self.searchBar valueForKey:#"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"Text change - %d",isSearching);
for (UIView *subview in searchBar.subviews)
{
if ([subview conformsToProtocol:#protocol(UITextInputTraits)])
{
[(UITextField *)subview setClearButtonMode:UITextFieldViewModeNever];
}
}
//Remove all objects first.
[filteredContentList removeAllObjects];
if([searchText length] != 0) {
isSearching = YES;
// [self searchTableList];
if([searchBar.placeholder isEqualToString:#"Search by course name"]){
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"courseName CONTAINS[cd] %#",_searchBar.text];
filteredContentList = [[listArray filteredArrayUsingPredicate:resultPredicate] mutableCopy];
}
else if([searchBar.placeholder isEqualToString:#"Search by category name"]){
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"category CONTAINS[cd] %#",_searchBar.text];
filteredContentList = [[listArray filteredArrayUsingPredicate:resultPredicate] mutableCopy];
}
}
else {
isSearching = NO;
// [searchBar resignFirstResponder];
}
// [self.tableView reloadData];
// [searchBar resignFirstResponder];
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Cancel clicked");
self.searchBar.text=#"";
[searchBar resignFirstResponder];
isSearching=NO;
[self.tableView reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Search Clicked");
// [self searchTableList];
//
[self.tableView reloadData];
[searchBar resignFirstResponder];
}
Here "isSearching" is bool values,
"listArray" is initial array,
"filteredContentList" is search array.
Related
I have a UITableViewController in which I am using Static Cells that are grouped. Each cell has a UITextField for users to enter info, and at the bottom is a submit button. Upon tapping the button, I verify that they have entered info for each of the fields and if not, I scroll up to that cell/field so that they can complete it.
However, for some reason it is not scrolling to the correct cell when using scrollToRowAtIndexPath:
#pragma mark - Save
- (IBAction)didTapSaveGuestDetails:(ZSSBottomOverlayButton *)sender {
[self checkForFormSubmissionErrors];
}
- (void)checkForFormSubmissionErrors {
// First Name
if (self.nameFirst.text.length == 0) {
[self showAlertWithMessage:NSLocalizedString(#"* Please enter first name", nil) fieldToHighlight:self.nameFirst];
return;
}
[self.view endEditing:YES];
[self submitUpdatedGuestInfo];
}
- (void)submitUpdatedGuestInfo {
}
#pragma mark - Alert
- (void)showAlertWithMessage:(NSString *)message fieldToHighlight:(UIView *)field {
UIColor *redColor = [OTAColors colorWithRed:234 green:85 blue:58];
[RKDropdownAlert title:message backgroundColor:redColor textColor:[UIColor whiteColor] time:2.0];
if (field) {
[self highlightField:field];
}
}
- (void)highlightField:(UIView *)field {
[self.tableView endEditing:YES];
// Color field
if ([field isKindOfClass:[ZSSLargeTextField class]]) {
ZSSLargeTextField *textField = (ZSSLargeTextField *)field;
[textField showWarning];
}
CGPoint pointInTable = [field convertPoint:field.bounds.origin toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:pointInTable];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
This exact implementation works great when using prototype cells, but NOT static.
However, if I use the following it does scroll to the correct cell:
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
So, it seems the issue could be in my convertPoint:toView: method?
Any idea what could be preventing it from scrolling to the correct cell?
[Edited Post]
For practicing, I developing a contact app without any backend. I followed only one NSMutableArray for maintaining contacts which is displayed in a UITableView.
Objective;
Like to search a contact (Ex: Dad), user given a name in a textfield and touch up a button
In the button action, check if Dad contain in the Mutable array which one i followed.
If present, then it definitely present in the tableView as a row. So i want to put selectionStyle for that row.
If search text changes means (Ex: Mom), then revert previous selectionStyle and apply to the row(Mom).
If not present, label notify "Not Present" as text. (Done!).
IBAction:
-(IBAction)actionSearchNameInTable:(id)sender{
if([myContactsArray containsObject:txtForContactName.text]){
myTable.tag=5;
NSInteger tempIndex=[myContactsArray indexOfObject:txtForContactName.text];
NSIndexPath *tempIndexPath=[NSIndexPath indexPathForRow:tempIndex inSection:0];
[self tableView:myTable didSelectRowAtIndexPath:tempIndexPath]; //broke here
NSLog(#"Call Passed!");
}
}
didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(myTable.tag==5){
NSLog(#"called done!");
//Here i like to select that row and apply selectionStyle or favorite background color for that cell, idea?.
myTable.tag=0;
}
These are all just other part of my application. I sured that, Delegate and Datasource are connected properly.
You are calling didDeselectRowAtIndexPath and not didSelectRowAtIndexPath.
And I think you have not implemented didDeselectRowAtIndexPath in your class so thats the reason of crash.
and for your another question:
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(cell.tag==100)
{
cell.contentView.backgroundColor=[UIColor grayColor];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[tblviw cellForRowAtIndexPath:indexPath];
cell.tag=100;
cell.contentView.backgroundColor=[UIColor grayColor];
}
Change this:
-(IBAction)actionSearchNameInTable:(id)sender{
if([myContactsArray containsObject:txtForContactName.text]){
myTable.tag=5;
NSInteger tempIndex=[myContactsArray indexOfObject:txtForContactName.text];
NSLog(#"TEmp index:%i",tempIndex);
NSIndexPath *tempIndexPath=[NSIndexPath indexPathForRow:tempIndex inSection:0];
NSLog(#"Temp IP:%#",tempIndexPath);
[self tableView:myTable didSelectRowAtIndexPath]; //broke here
NSLog(#"Call Passed!");
}
}
And for custom selection background do this in your cellForRowAtIndexPath.
UIView *customColorView = [[UIView alloc] init];
customColorView.backgroundColor = [UIColor colorWithRed:180/255.0
green:138/255.0
blue:171/255.0
alpha:0.5];
cell.selectedBackgroundView = customColorView;
Hope this helps.. :)
EDIT:
didSelectRowAtIndexPath is a delegate. It only get called when user interaction happens. I face a same problem some days ago. I did it in cellForRowAtIndexPath. For selecting a row do this:
if ([[myContactsArray objectAtIndex:indexPath.row] isEqualToString:txtForContactName.text]) {
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
Please try to see my edited answer...
-(IBAction)actionSearchNameInTable:(id)sender{
if([myContactsArray containsObject:txtForContactName.text]){
myTable.tag=5;
NSInteger tempIndex=[myContactsArray indexOfObject:txtForContactName.text];
NSLog(#"TEmp index:%i",tempIndex);
NSIndexPath *tempIndexPath=[NSIndexPath indexPathForRow:tempIndex inSection:0];
NSLog(#"Temp IP:%#",tempIndexPath);
[self tableView:myTable didSelectRowAtIndexPath:tempIndexPath]; //Change here......
NSLog(#"Call Passed!");
}
}
Action for searching that if given text is present or not:
-(IBAction)actionSearchNameInTable:(id)sender{
[txtForContactName resignFirstResponder];
if([myContactsArray containsObject:txtForContactName.text]){
myTable.tag=5;
[myTable reloadData];
}
}
In cellForRowAtIndexPath:
//Better delegate to apply selection style
//Code after dequeue...
myTableCell.textLabel.text=[myContactsArray objectAtIndex:indexPath.row];
myTableCell.imageView.image=[myContactsPhotosArray objectAtIndex:0];
{
myTableCell.textLabel.text=[myContactsArray objectAtIndex:indexPath.row];
myTableCell.imageView.image=[myContactsPhotosArray objectAtIndex:0];
if(myTable.tag==5){
NSLog(#"Ready to apply selectionStyle");
if ([[myContactsArray objectAtIndex:indexPath.row] isEqualToString:txtForContactName.text]) {
[myTable selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
myTable.tag=0;
}
}
return myTableCell;
}
Using parse.com's PFQueryTableViewController. All is working fine with a search bar also. The problem I have now is my "load more" which is a feature included with this new tableViewController isn't showing anymore.
I guess it's something to do with me overriding the tableView:numberOfRowsInSection: method. Everything else seems to be working as normal. Correct number of results are returned, pull to refresh works fine. I have a feeling the functionality for "load more" is still there but because I added that number of rows method I've overridden it's default behavior and now the load more row isn't visible.
My initializer:
#interface MPPeopleTableViewController () <UISearchDisplayDelegate, UINavigationBarDelegate>
{
NSMutableArray *people;
NSArray *searchResults;
}
#end
#implementation MPPeopleTableViewController
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// This table displays items in my People class on parse.com
[self setParseClassName: #"People"];
[self setPullToRefreshEnabled: YES];
[self setPaginationEnabled: YES];
[self setObjectsPerPage: 5];
}
return self;
}
Query for table:
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache
// first to fill the table and then subsequently do a query
// against the network.
if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[query whereKey:#"active" equalTo:#1];
[query orderByDescending:#"createdAt"];
return query;
}
Methods for search bar:
- (void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
searchResults = [[self objects] filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[[[self searchDisplayController] searchBar] scopeButtonTitles]
objectAtIndex:[[[self searchDisplayController] searchBar] selectedScopeButtonIndex]]];
return YES;
}
Datasource methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (tableView == [[self searchDisplayController] searchResultsTableView]) {
return [searchResults count];
} else {
return [[self objects] count];
}
}
Final datasource method:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
PFObject *current;
if (tableView == [[self searchDisplayController] searchResultsTableView]) {
current = [searchResults objectAtIndex:indexPath.row];
} else {
current = [[self objects] objectAtIndex:indexPath.row];
}
// Maybe need to grab image synchro instead
PFFile *userImageFile = current[#"image"];
[userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
cell.textLabel.text = [current objectForKey:#"name"];
cell.detailTextLabel.text = [current objectForKey:#"notes"];
}];
return cell;
}
I have a strong feeling the issue is coming from the number of rows method. Everytime I try to add an extra row my app crashes. I think I'm missing something. All I do is add +1 after the line that returns my number of rows e.g. return [[self objects] count] + 1; and this causes the app to crash.
Can you show and explain the steps I need to take to add that extra row that is needed for the "Load More" row. When I remove the number of rows method is comes back and all is fine but then my search feature doesn't work.
Would appreciate some help thanks.
Kind regards
Update
Updated number of rows in section method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == [[self searchDisplayController] searchResultsTableView]) {
return [searchResults count];
} else {
return [[self objects] count] + 1;
}
}
Updated cell for row and index path method:
if (indexPath.row == self.objects.count) {
cell.textLabel.text = #"Load More";
} else {
PFObject *current;
if (tableView == [[self searchDisplayController] searchResultsTableView]) {
current = [searchResults objectAtIndex:indexPath.row];
} else {
current = [[self objects] objectAtIndex:indexPath.row];
}
// Maybe need to grab image synchro instead
PFFile *userImageFile = current[#"image"];
[userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
cell.textLabel.text = [current objectForKey:#"name"];
cell.detailTextLabel.text = [current objectForKey:#"notes"];
}];
}
What you return in numberOfRowsInSection: is taken as gospel for how many rows you have. In addition, you MUST in your cellForRowAtIndexPath: be able to handle providing a cell for any of those rows, which means if the additional row presents an index that is higher than the count of either searchResults or [self objects], then you overstepped a bound. I'd put a breakpoint in
if (tableView == [[self searchDisplayController] searchResultsTableView]) {
when you add the row and see how many are in the array, and what the value of indexPath.row is.
Yes, the app will crash if you tell it that there is an extra row, because it will then call cellForRowAtIndexPath one extra time, and exceed the bounds of the array of objects.
If you want to force an extra row like that, you would also need to handle the extra row specifically in cellForRow...
I am not sure how the "Load more" function works. I had pagination set to YES once, but didn't get a Load more-row. I didn't need it, so I just set it to NO.
If you remove the +1, the app doesn't crash, right?
In cellForRow, check if the indexPath.row == self.objects.count. If it is, then you have the "Load more" row, and need to handle that specifically. Then, in didSelectRowAtIndexPath, you can load more results.
UPDATE
This is a slightly edited example code from the Anypic tutorial app (because that uses 1 section for each object). As NSIndexPath starts on index 0, the test against self.objects.count should then point to the row AFTER the last (meaning the extra pagination cell). I believe this should work for you:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row == self.objects.count && self.paginationEnabled) {
// Load More Cell
[self loadNextPage];
}
}
My final solution was to do this an entirely different way. I've pasted code and comments below to show others exactly how. Hope this helps.
Inside my viewWillAppear:
- (void)viewWillAppear:(BOOL)animated {
// Create a new view to a specific size
UIView *loadMoreView = [[UIView alloc] initWithFrame:CGRectMake(0, 718, 239, 50)];
[loadMoreView setBackgroundColor:[UIColor clearColor]];
// Make this view the footer of my tableview
[[self tableView] setTableFooterView: loadMoreView];
// Create the button
UIButton *loadMoreButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
// Set the size of the button to fill up the view it's within
[loadMoreButton setFrame: loadMoreView.bounds];
// Set the title and colour
[loadMoreButton setTitle:#"Load More" forState:UIControlStateNormal];
// Connect up an action to trigger loadNextPage method when button is tapped
[loadMoreButton addTarget:self action:#selector(loadMoreButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
// Add this new button to the loadMoreView
[loadMoreView addSubview:loadMoreButton]; // add the button to bottom view
}
IBAction for loading more results:
- (IBAction)loadMoreButtonTapped:(id)sender {
[self loadNextPage];
}
I have a UITableView of custom UITableViewCells each with two UITextFields in them. When I select a UITextField in the opening view i.e. without scrolling select a UITextField in the opening view. It becomesFirstResponder and I can enter text, as I hit enter all UITextFields in the opening view can becomeFirstResponder but when I get to the end of the UITableViewCells of that opening view and try to load the next UITableViewCell that is currently out of view and set its UITextField to becomeFirstResponder it doesn't work.
I have set up a if statment inside textFieldShouldReturn and it confirms that the textField is returning NO to becomeFirstResponder.
I would like to know how to fix this; I have looked for solutions but have yet to find anything that fits my situation. Below are the UITextFieldDelegates that I am using as I think in here I am supposed to do something like call or load the next UITableViewCell, but I do not know how.
#pragma mark - Textfield Delegates
-(BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
if ([textField isEqual:cell.widthTexField]) {
nWidth = [[sortedItemsArray objectAtIndex:textField.tag] valueForKey:#"w_MM"];
} else if ([textField isEqual:cell.heightTextField]) {
nHeight = [[sortedItemsArray objectAtIndex:textField.tag] valueForKey:#"h_MM"];
}
return YES;
}
-(BOOL)textFieldShouldBeginEditing:(UITextField*)textfield {
int height = self.finishingTableView.frame.size.height;
NSLog(#"%i", height);
self.finishingTableView.frame= CGRectMake(self.finishingTableView.frame.origin.x, self.finishingTableView.frame.origin.y, self.finishingTableView.frame.size.width, 307);
// select correct row
if (textfield.tag > 999999) {
int adjustTag = textfield.tag-1000000; // remove a million so that you have the text fields correct position in the table. (this is only for height textfields)
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:adjustTag inSection:0];
[finishingTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self tableView:finishingTableView didSelectRowAtIndexPath:indexPath];
[self.finishingTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
return YES;
} else {
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:textfield.tag inSection:0];
[finishingTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self tableView:finishingTableView didSelectRowAtIndexPath:indexPath];
[self.finishingTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
return YES;
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(#"%i", textField.tag+1);
[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
BOOL success = [[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
if (success) {
NSLog(#"HypnosisView became the first responder");
} else {
NSLog(#"Could not become first responder");
}
// this means there has been a change in the UItextfield
NSLog(#"%#", selectedItemDictionary);
if (textField.tag < 999999) {
tempFinishingObjectDictionary = [selectedItemDictionary mutableCopy];
if (![textField.text isEqualToString:[selectedItemDictionary objectForKey:#"w_MM"]]) {
tempUpdatedRow = #"T";
// remove kevalues
[tempFinishingObjectDictionary removeObjectForKey:#"updatedRow"];
[tempFinishingObjectDictionary removeObjectForKey:#"new_w_MM"];
// update keyvalues
[tempFinishingObjectDictionary setValue:tempUpdatedRow forKey:#"updatedRow"];
[tempFinishingObjectDictionary setValue:textField.text forKey:#"new_w_MM"];
}
} else {
if (![textField.text isEqualToString:[selectedItemDictionary objectForKey:#"h_MM"]]) {
tempUpdatedRow = #"T";
// remove kevalues
[tempFinishingObjectDictionary removeObjectForKey:#"updatedRow"];
[tempFinishingObjectDictionary removeObjectForKey:#"new_h_MM"];
// update keyvalues
[tempFinishingObjectDictionary setValue:tempUpdatedRow forKey:#"updatedRow"];
[tempFinishingObjectDictionary setValue:textField.text forKey:#"new_h_MM"];
}
}
NSLog(#"%#", tempFinishingObjectDictionary);
[coreDataController editSelectedFinishing:htmlProjID UpdatedNSD:tempFinishingObjectDictionary SelectedRow:selectedItemIndexPathRow];
[SVProgressHUD dismiss];
NSLog(#"%#", selectedItemDictionary);
return YES;
}
In your textFieldShouldReturn when you go to the next cell you should check if two cells out is off the screen (and therefore not existent). If it is iff the screen you should scroll the table by one cell
[tableview setContentOffset:CGPointMake(tableview.contentOffset.x,tableview.contentOffset.y + cellHeight) animated:YES];
You will have to adjust this scrolling to your liking as I don't know how your application flows.
I have two UITextFields on each UITableViewRow, and for some reason when I press return on the UIKeyboard one particular rows neither of the two UITextFields will reaspond (the cursor is not visible).
I have a custom UITableViewCell that I am using, I can show you the code for this if you like however I dont think that is the problem as the return key works for 95% of the UITableViewCells. So I was thinking maybe it was how I was handling the delegate methods for the UITextFields?
This is the code I am using for the delegate methods.
-(BOOL)textFieldShouldBeginEditing:(UITextField*)textfield {
int height = self.finishingTableView.frame.size.height;
self.finishingTableView.frame= CGRectMake(self.finishingTableView.frame.origin.x, self.finishingTableView.frame.origin.y, self.finishingTableView.frame.size.width, 307);
// select correct row
if (textfield.tag > 999999) {
int adjustTag = textfield.tag-1000000; // remove a million so that you have the text fields correct position in the table. (this is only for height textfields)
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:adjustTag inSection:0];
[finishingTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self tableView:finishingTableView didSelectRowAtIndexPath:indexPath];
[self.finishingTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
return YES;
} else {
NSIndexPath *indexPath =[NSIndexPath indexPathForRow:textfield.tag inSection:0];
[finishingTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self tableView:finishingTableView didSelectRowAtIndexPath:indexPath];
[self.finishingTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
return YES;
}
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSLog(#"%i", textField.tag+1);
[[self.view viewWithTag:textField.tag+1] becomeFirstResponder];
// this means there has been a change in the UItextfield
NSLog(#"%#", selectedItemDictionary);
if (textField.tag < 999999) {
tempFinishingObjectDictionary = [selectedItemDictionary mutableCopy];
if (![textField.text isEqualToString:[selectedItemDictionary objectForKey:#"mMM"]]) {
tempUpdatedRow = #"T";
// remove kevalues
[tempFinishingObjectDictionary removeObjectForKey:#"updatedRow"];
[tempFinishingObjectDictionary removeObjectForKey:#"new_mMM"];
// update keyvalues
[tempFinishingObjectDictionary setValue:tempUpdatedRow forKey:#"updatedRow"];
[tempFinishingObjectDictionary setValue:textField.text forKey:#"new_mMM"];
}
} else {
if (![textField.text isEqualToString:[selectedItemDictionary objectForKey:#"hMM"]]) {
tempUpdatedRow = #"T";
// remove kevalues
[tempFinishingObjectDictionary removeObjectForKey:#"updatedRow"];
[tempFinishingObjectDictionary removeObjectForKey:#"new_hMM"];
// update keyvalues
[tempFinishingObjectDictionary setValue:tempUpdatedRow forKey:#"updatedRow"];
[tempFinishingObjectDictionary setValue:textField.text forKey:#"new_hMM"];
}
}
NSLog(#"%#", tempFinishingObjectDictionary);
[coreDataController editSelectedFinishing:htmlProjID UpdatedNSD:tempFinishingObjectDictionary SelectedRow:selectedItemIndexPathRow];
[SVProgressHUD dismiss];
NSLog(#"%#", selectedItemDictionary);
return YES;
}
I don't have any idea on where to look or how to find this error as it seems so random, but happens on the same UITextFields every time.
The code above is where I think the problem could lie; however, having logged everything and debugged for several hours, I am starting to think it's a bug with UITextFields in UITableViewCells.
is [[self.view viewWithTag:textField.tag+1] canBecomeFirstResponder] == YES?
also you need to resign the current UITextField before setting the next as the first responder
[textField resignFirstResponder];