I have this code:
for (NSIndexPath *indexPath in tableView.indexPathsForSelectedRows) {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
I have a search bar that filters out search objects and puts a check mark on the cell when you click it. However, if you search and click on the first cell, it checks it off. But if you delete the search text, the check mark shows up on the first cell, not the one that I checked off. Here is a video showing this:
https://docs.google.com/file/d/0B1Of4oDADQCQZkF0aGdhdmF0VjA/edit
Where do I put the code above in the code below so that the checkmark stays with the selected cell?
#import "MSAddFriendsViewController.h"
#interface MSAddFriendsViewController ()
#end
#implementation MSAddFriendsViewController
- (void)viewDidLoad
{
[super viewDidLoad];
PFQuery *query = [PFUser query];
[query orderByAscending:#"username"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error %#, %#", error, [error userInfo]);
}
else {
self.allUsers = objects;
[self.tableView reloadData];
}
}];
self.currentUser = [PFUser currentUser];
self.searchUsers.delegate = self;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (searchText.length == 0) {
self.userResults = nil;
[self.tableView reloadData];
return ;
}
self.userResults = [NSMutableArray array];
for (PFUser *user in self.allUsers) {
if ([user.username rangeOfString:searchText
options:(NSAnchoredSearch | NSCaseInsensitiveSearch)].location == 0) {
[self.userResults addObject:user];
}
}
[self.tableView reloadData];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if (self.userResults != nil) {
return [self.userResults count];
}
// Return the number of rows in the section.
return [self.allUsers count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *user;
if (self.userResults != nil) {
user = [self.userResults objectAtIndex:indexPath.row];
} else {
user = [self.allUsers objectAtIndex:indexPath.row];
}
cell.textLabel.text = user.username;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
PFRelation *friendsRelation = [self.currentUser relationforKey:#"friendsRelation"];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
[friendsRelation addObject:user];
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
} }];
}
#end
Can someone please correct the code above?
The first block of code just deselects all of the selected rows. This isn't the solution to your problem. There are a few fundamental issues with your code in general that need correcting...
First off -- you need to keep an array of the selected cells, indexed as the full (non-searching) table is indexed. For example, if there's text in the search bar and the first row is selected, your selected cell array should also indicate the selection boolean of the preceding and following rows not currently visible, and do so all in order.
Secondly -- you need to explicitly set the checkmarks in your cells' accessory views during your cellForRowAtIndexPath: method in order to indicate your selected cells. The only reason that you have a checkmark in the first cell after the search bar is cleared and the table's reloaded is because the cell's being reused (i.e. [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]).
By fixing these first and second issues, you should be off to a good start... When you're not searching, the selected cell array should contain the appropriate selection booleans for all the cells in proper order; and when you are searching, you have to filter the selected cell array in just the same way you'd filter your table based on the search text. And instead of adding checkmarks during didSelectRowAtIndexPath:, you would be better off just indicating that the cell is selected in the selected cell array then reloading table to display the appropriate checkmark.
Related
I am attempting to work a segmented control to display data from a search into categories. However although data is received it is not being displayed on my table. Here is my code for the two View Controllers. The child View controller is the one in which the UITableView is stored.
PARENT VC
- (void)searchPeople:(NSString*)text {
if(![text isEqualToString:#""]){
PFQuery *userWithName = [PFQuery queryWithClassName:#"_User"];
[userWithName whereKey:#"fullName" containsString:text];
PFQuery *userWithHandle = [PFQuery queryWithClassName:#"_User"];
[userWithHandle whereKey:#"username" containsString:text];
PFQuery *userQuery = [PFQuery orQueryWithSubqueries:#[userWithHandle,userWithName]];
[userQuery findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
NSLog(#"USERS: %#",results);
[self.userResults removeAllObjects];
[self.userResults addObjectsFromArray:results];
[[ArrayManager sharedInstance].searchResults addObjectsFromArray:results];
NSLog(#"Count Number: %#", [ArrayManager sharedInstance].searchResults);
[[NSNotificationCenter defaultCenter] postNotificationName:#"reload_data" object:self];
}];
}
}
CHILD VC
-(void)handle_data {
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Object Entries: %lu", (unsigned long)[[ArrayManager sharedInstance].searchResults count]);
NSMutableArray * array = [[ArrayManager sharedInstance] getGlobalArray];
return [array count];
}
- (void)tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *data = [[ArrayManager sharedInstance]init].searchResults[indexPath.row];
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
cell.textLabel.text = data[#"objectId"];
return cell;
}
Data is returned fine from the server however, there is no data being displayed on the table. The ArrayManager class is a Singleton class.
Create a Data Access Object (DAO) and store all information in an array in that.
http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
Have both VC's change and access the DAO instead of each other. It is much simpler that way.
I am working with parse on a little app. It should show names, where stored on parse user class in an Array column.
Here is my Code:
#synthesize friendsList;
-(void)viewDidLoad{
[super viewDidLoad];
PFQuery*query = [PFUser query];
[query getObjectInBackgroundWithId:#"myObjectId" block:^(PFObject *gameScore, NSError *error) {
if(error==nil){
friendsList = [gameScore valueForKey:#"Friends"];
NSLog(#"%#", friendsList);
}
else{
NSLog(#"Error");
}
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [friendsList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell" forIndexPath:indexPath];
cell.textLabel.text = friendsList[indexPath.row];
return cell;
}
The problem is, when I am loading the data from parse. It does't show anything on the table view.
Do I declare friendsList likt this:
friendsList = [NSMutableArray arrayWithObjects:#"Name1", #"Name2", nil];
It will work.
Your tableView is blank as your friendsList is not populated when the tableView is displayed.
In the completion block reload the tableView.
In your completion block after friendsList = [gameScore valueForKey:#"Friends"]; statement add following code:
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData]; // assuming your table view is tableView
});
Hope this helps!
I think you missed allocating the array
friendsList = [[NSMutableArray alloc] init];
I'm working on a project and I want the user to be able to search a list on a UITableView. I've added the search bar and connected it to the search display controller. I have no idea how to actually search the list and grab the data from parse, filter it, set it to the PFUser of toUser, and display it. Anyone know how to do this?
Here's the code where I save the message:
if (toUser!= nil){
app[#"toUser"]=toUser;
}
[app save];
Here are some code snippets for the table view:
This displays the users and filters out the current user:
ParseExampleAppDelegate *delegate=[[UIApplication sharedApplication] delegate];
PFQuery *query = [PFUser query];
users = [[query findObjects] mutableCopy];
for(PFUser *user in users){
if ([user.objectId isEqualToString:delegate.applicationUser.objectId]){
[users removeObject:user];
break;
}
}
[users removeObject:delegate.applicationUser];
NSLog(#"all user: %lu",users.count);
[self.usersTable setDelegate:self];
[self.usersTable setDataSource:self];
[self.usersTable reloadData];
[self.usersTable reloadData];
Some methods for the table view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"userCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
PFObject *tempObject = [users objectAtIndex:indexPath.row];
cell.text= [tempObject objectForKey:#"username"];
return cell;
NSMutableArray *filteredStrings;
BOOL isFiltered;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"users:%lu",[users count]);
return [users count];
}
Thanks for your help,
armanb21
I'm retrieving data from parse and put it the tableview but when I'm trying to also add a searchbar I don't know how can I manage it. What should I do on tableView:cellForRowAtIndexPath: method instead of NSLog(#"do something!!");
My code is below and thanks for any help.
retrieve from parse code is below
- (void) retrieveFromParse {
PFQuery *retrieveName = [PFQuery queryWithClassName:#"pFihrist"];
[retrieveName findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
nameArray = [[NSMutableArray alloc] initWithArray:objects];
}
[tableView reloadData];
}];
}
UITableView Delegate code is below
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [nameArray count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"fCell";
FihristCell *cell = (FihristCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[FihristCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.tableView) {
PFObject *tempObject = [nameArray objectAtIndex:indexPath.row];
cell.cellProfName.text = [tempObject objectForKey:#"pName"];
} else {
NSLog(#"do something!!");
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"cell tapped");
}
search methods code is below
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
searchResults = [nameArray filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
First Register the Cell to display you searched items
You have to register the cell to searchdisplaycontroller as well.
Important: You must register a class or nib file using the registerNib:forCellReuseIdentifier: or registerClass:forCellReuseIdentifier: method before calling this method.
in View did load
If you are Creating cell in code
[self.searchDisplayController.searchResultsTableView registerClass:[TableViewCell class]
forCellReuseIdentifier:#"IdentifierForCell"];
If you are Creating cell in nib
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"CellNibName" bundle:nil]
forCellWithReuseIdentifier:#"IdentifierForCell"];
2. Deque corresponding cell to search display controller table with identifier
FihristCell *cell = (FihristCell *)[self.searchDisplayController.searchResultsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
3. configure that cell to display instead of NSLog
I'm new to objective-C and I am having an issue populating my UItableview with data I retrieved from Parse.
Here is my query:
- (void)viewDidLoad {
[super viewDidLoad];
PFQuery *query = [PFUser query];
[query orderByAscending:#"username"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
} else {
//this is my users array
self.allUsers = objects;
[self.tableView reloadData];
}
}];
I have logged this and can see that I successfully retrieved the data. But when I try to populate my tableView as follows. No data shows up. What am I doing wrong?
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.allUsers count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
cell.textLabel.text = user.username;
return cell;
}
Thanks in Advance for any help.
You need to implement:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView.