As an example, I am trying to load a place name into my top UITableView, called myTableView. On the bottom, I am trying to display only "test2."
Naturally, all the data is being loaded into each UITableView. If I scroll to the bottom of myTableView2, the word "test2" IS shown, but I would like it to be the only thing there.
Is there a way, maybe by delegating different data sources, that I can separate the data I wan in each UITableView? I tried separating by if statements but quickly realized that had no effect.
It seems to me that I may need to set a separate datasource for myTableView2, but I am not sure how to do that...
Code is here:
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
[self setString];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSString *string1 = [dic objectForKey:#"name"];
for (NSDictionary *diction in dic)
{
[array addObject:string1];
}
[[self myTableView] reloadData];
NSString *string2 = [NSString stringWithFormat:#"test2"];
[array addObject:string2];
[[self myTableView2] reloadData];
[indicator stopAnimating];
indicator.hidden=YES;
[indicator removeFromSuperview];
ilabel.hidden = YES;
}
Solved with the code below. The key was to have two different arrays to load the respective data in, and display it at the very bottom where I am able to distinguish between UITableViews with IF statements:
- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
[self setString];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSString *string1 = [dic objectForKey:#"name"];
NSString *string2 = [NSString stringWithFormat:#"test2"];
for (NSDictionary *diction in dic)
{
[array addObject:string1];
[array2 addObject:string2];
[[self myTableView] reloadData];
[[self myTableView2] reloadData];
}
[indicator stopAnimating];
indicator.hidden=YES;
[indicator removeFromSuperview];
ilabel.hidden = YES;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.myTableView)
{
if ([[array objectAtIndex:indexPath.row] isKindOfClass:[NSNumber class]])
{
cell.textLabel.text = [[array objectAtIndex:indexPath.row] stringValue];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
else
{
cell.textLabel.text = [array objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
}
if (tableView == self.myTableView2)
{
if ([[array2 objectAtIndex:indexPath.row] isKindOfClass:[NSNumber class]])
{
cell.textLabel.text = [[array2 objectAtIndex:indexPath.row] stringValue];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
else
{
cell.textLabel.text = [array2 objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
}
return cell;
}
Related
Here I parsed my json data and kept in json and I have to insert into the tableviewcell which is designed custom...here I posted the json parsed code and tableview cell...can somebody please help me with this...
NSString *urlstring =#"https://bsedemo.com/instasocial/api/post/feeds?user_id=402&&access_token=$2y$10$TWX2Ym1gM4NBjGCNzTydzuQTZWPcK2tMVw1eWdWvYDFmO4CsKc1kC&&page_no=1&&feed_type=3&&feed_id=&&member_id=402";
NSURL *url = [NSURL URLWithString:urlstring];
[[NSURLSession.sharedSession dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
{
NSError *err;
NSDictionary * jsondata = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSMutableArray *json =[[NSMutableArray alloc] initWithObjects:[jsondata objectForKey:#"result"],nil];
if(err)
{
NSLog(#"Failed to load json:%#",err);
return;
}
for (int i=0;i<json.count;i++)
{
NSLog(#"json:%#",json[i]);
}
for (NSDictionary *dict in json) {
self->user_image = [dict valueForKey:#"user_image"];
self->username = [dict valueForKey:#"user_name"];
self->created_at =[dict valueForKey:#"created_at"];
self->post_text = [dict valueForKey:#"post_text"];
self->post_comment_count = [dict valueForKey:#"post_comment_count"];
self->post_like_count = [dict valueForKey:#"post_like_count"];
//self->media_img = dict[#"media"][0][#"media_image"];
}
}]resume];
[self->tableview reloadData];
Here I posted the tableview and tableviewcell code which I tried...if I done wrong please correct the code...Thanks in advance!!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;//name.count;
}
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Cell";
TableViewCellVC *cell = [[TableViewCellVC alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
/*TableViewCellVC *cell = (TableViewCellVC *)*/
cell=[tableview dequeueReusableCellWithIdentifier:simpleTableIdentifier forIndexPath:indexPath];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"TableViewCellVC" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.profileImageView.image = [UIImage imageNamed:#"girl1.jpg"]; //[UIImage imageNamed:[user_image objectAtIndex:indexPath.row]];
cell.profileImageView.layer.cornerRadius = 23.5;
//cell.profileImageView.backgroundColor = [UIColor blackColor];
//[cell.usernameLabel setFont:[UIFont fontWithName:#"Raleway-Thin" size:15]];
cell.usernameLabel.text =[name objectAtIndex:indexPath.row];//[username objectAtIndex:indexPath.row];
//[cell.lastseenLabel setFont:[UIFont fontWithName:#"Raleway-Thin" size:12]];
cell.lastseenLabel.text = #"Today at 23:52";//[created_at objectAtIndex:indexPath.row];
//[cell.discriptionLabel setFont:[UIFont fontWithName:#"Raleway-Thin" size:10]];
cell.discriptionLabel.text =#"All our dreams can come true, if we have the courage to pursue them. – Walt Disney. All our dreams can come true, if we have the courage to pursue them. – Walt Disney.";//[post_text objectAtIndex:indexPath.row];
cell.postImageView.image = [UIImage imageNamed:#"postpic.jpg"];
//media_img[indexPath.row];
// [cell.likeLabel setFont:[UIFont fontWithName:[NSString fontAwesomeIconStringForEnum:FAHeart] size:16]];
cell.likeLabel.text =[NSString fontAwesomeIconStringForEnum:FAHeart];
//[post_like_count objectAtIndex:indexPath.row];
cell.commentLabel.text =[NSString fontAwesomeIconStringForEnum:FAComment]; //[post_comment_count objectAtIndex:indexPath.row];
cell.shareLabel.text=[NSString fontAwesomeIconStringForEnum:FAShare];
cell.moreLabel.text=[NSString fontAwesomeIconStringForEnum:FADotCircleO];
return cell;
}
-(void)tableView
{
tableview = [[UITableView alloc] initWithFrame:CGRectMake(0,topbar.frame.origin.y+topbar.frame.size.height,[UIScreen mainScreen].bounds.size.width,[UIScreen mainScreen].bounds.size.height-150) style:UITableViewStylePlain];
tableview.delegate = self;
tableview.dataSource = self;
//tableview.rowHeight=UITableViewAutomaticDimension;
//tableview.estimatedRowHeight=400;
tableview.separatorColor = [UIColor blackColor];
[tableview registerNib:[UINib nibWithNibName:#"TableViewCellVC" bundle:nil]
forCellReuseIdentifier:#"Cell"];
[mainview addSubview:tableview];
}
When my user searches for something inside a tableview, when no results are returned, my app shows the standard "No Results" placeholder inside the tableview. That said, when no results exist, I want to return one populated cell (cell populated with default data). How can I accomplish this? I tried the below, but I still get 'No Results' returned?
ViewController.m
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
if ([searchResults count] == 0) {
return 1;
} else {
return [searchResults count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *NetworkTableIdentifier = #"sidebarCell";
self.sidetableView.separatorStyle = UITableViewCellSeparatorStyleNone;
sidebarCell *cell = (sidebarCell *)[tableView dequeueReusableCellWithIdentifier:NetworkTableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"sidebarCell" owner:self options:nil];
cell = nib[0];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSDictionary *userName = searchResults[indexPath.row];
NSString *first = userName[#"first name"];
NSString *last = userName[#"last name"];
[[cell username] setText:[NSString stringWithFormat:#"%# %#", first, last]];
NSDictionary *userlast = searchResults[indexPath.row];
[[cell lastName] setText:userlast[#"last name"]];
NSDictionary *userBio = searchResults[indexPath.row];
[[cell userDescription] setText:userBio[#"userbio"]];
NSString *area = userName[#"neighbourhood"];
NSString *city = userName[#"city"];
[[cell areaLabel] setText:[NSString stringWithFormat:#"%#, %#", area, city]];
NSString *profilePath = searchResults[indexPath.row][#"photo_path"];
[cell.usermini sd_setImageWithURL:[NSURL URLWithString:profilePath]];
if ([searchResults count] == 0) {
NSLog(#"SEARCH RESULTS ARE %#", searchResults);
[[cell username] setText:[NSString stringWithFormat:#"%#", self.searchBar.text]];
[[cell lastName] setText:userlast[#""]];
[[cell userDescription] setText:#"This friend is not on the app (yet!) Tap to invite them."];
[[cell areaLabel] setText:[NSString stringWithFormat:#""]];
NSString *profileDefault = #"http://url.com/user.png";
[cell.usermini sd_setImageWithURL:[NSURL URLWithString:profileDefault]];
return cell;
}
return cell;
}
I don't really recommend doing this, as you should return an empty list, if there are no search results. That is consistent with User Interface Guidelines. But, if you insist, you could create a default object and initialize your searchResults array with that object and return 1 from the numberOfRows method. Something like this:
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
if ([searchResults count] == 0) {
NSDictionary *dict = [NSDictionary dictionaryWithObjects:#[#“Enter First Name”, #“Enter Last Name”, #“Enter User Bio”, #“Enter Neighborhood”, #“Enter City”, #“Enter Photo Path”]
forKeys: #[#“first_name”, #“last_name, #“userbio”, #“neighbourhood”, #“city”, #“photo_path”];
searchResults = [NSArray arrayWithObjects: dict, nil];
return 1;
}
else {
return [searchResults count];
}
}
And, you can greatly simplify your cellForRowAtIndexPath code as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NetworkTableIdentifier = #"sidebarCell";
self.sidetableView.separatorStyle = UITableViewCellSeparatorStyleNone;
sidebarCell *cell = (sidebarCell *)[tableView dequeueReusableCellWithIdentifier:NetworkTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"sidebarCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
//Note, I like to name my local variables the same as the dictionary keys just to eliminate any confusion
NSDictionary *userObject = [searchResults objectAtIndex:indexPath.row];
NSString *first_name = [userObject objectForKey:#"first name"];
NSString *last_name = [userObject objectForKey:#"last name"];
NSString *userbio = [userObject objectForKey:#“userbio”];
NSString *neighbourhood = [userObject objectForKey:#“neighbourhood”];
NSString *city = [userObject objectForKey:#“city”];
NSString *photo_path = [userObject objectForKey:#“photo_path”];
[[cell username] setText:[NSString stringWithFormat:#"%# %#", first_name, last_name]];
[[cell lastName] setText:last_name];
[[cell userDescription] setText:userbio];
[[cell areaLabel] setText:[NSString stringWithFormat:#"%#, %#", neighbourhood, city]];
[[cell usermini] sd_setImageWithURL:[NSURL URLWithString:photo_path]];
}
return cell;
}
I did something like this in my app. It's ugly and I'm not recommending you following this way. I did it only because I was kind of lazy about layouts and placing the placeholder in the correct place in the view hierarchy and handle all those hide/show situations. My view controller has a very complex hierarchy of views and the table view was one that has already had all I needed (resize automatically when the status or toolbar is showing).
What I suggest you is to hide the table view when there is an empty search result and substitute it with your placeholder.
Try this it's working:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger numOfSections = 0;
if (arrData.count>0)
{
self.TblView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
numOfSections = 1;
self.TblView.backgroundView = nil;
}
else
{
UILabel *noDataLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.TblView.bounds.size.width, self.TblView.bounds.size.height)];
noDataLabel.text = #"No Results";
noDataLabel.textColor = [UIColor blackColor];
noDataLabel.textAlignment = NSTextAlignmentCenter;
self.TblView.backgroundView = noDataLabel;
self.TblView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
return numOfSections;
}
I have two tables, one table for usernames, and one table for scores. I populate those tables with two arrays. The tables need to be in descending order based on the scores. I sort the array with the scores in it, but I am not sure how I can arrange the usernames to stick with their score, they are in a separate array, and a separate table from the scores table. Here is my code:
dictionary = [NSDictionary dictionaryWithObjects:matchesForUser forKeys:tableData];
sortedFirstArray = [dictionary allKeys];
sortedSecondArray = [dictionary objectsForKeys:sortedFirstArray notFoundMarker:[NSNull null]];
sortedSecondArray = [sortedSecondArray sortedArrayUsingSelector: #selector(compare:)];
I need the sortedFirstArray values to stick with their respective sortedSecondArray values in terms of their order in each of their arrays.
UPDATE
My code attempting to do the sorting:
PFQuery *query = [PFQuery queryWithClassName:#"_User"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!error) {
entries = [NSMutableArray new];
for (PFObject *object in objects) {
NSLog(#"%#", object.objectId);
[tableData addObject:[object valueForKey:#"username"]];
[matchesForUser addObject:[object valueForKey:#"matches"]];
NSMutableDictionary* entry = [NSMutableDictionary new];
entry[#"username"] = [object valueForKey:#"username"];
entry[#"matches"] = [object valueForKey:#"matches"];
[entries addObject:entry];
//transfer = entries;
}
transfer = [entries sortedArrayUsingComparator:^NSComparisonResult(NSDictionary* a, NSDictionary* b) {
NSDate *first = [a objectForKey:#"matches"];
NSDate *second = [b objectForKey:#"matches"];
NSLog(first);
NSLog(second);
return [first compare:second];
}];
//dictionary = [NSDictionary dictionaryWithObjects:matchesForUser forKeys:tableData];
//sortedFirstArray = [dictionary allKeys];
//sortedSecondArray = [dictionary objectsForKeys:sortedFirstArray notFoundMarker:[NSNull null]];
//sortedSecondArray = [sortedSecondArray sortedArrayUsingSelector: #selector(compare:)];
[_tableView reloadData];
[_tableViewScore reloadData];
}else{
NSLog([error description]);
}
NSLog(#"***tabledata***");
NSLog([NSString stringWithFormat:#"%lu", (unsigned long)[tableData count]]);
NSLog(#"***matchesdata***");
NSLog([NSString stringWithFormat:#"%lu", (unsigned long)[matchesForUser count]]);
});
}];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(tableView.tag == 1) {
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.textLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:16.0];
cell.textLabel.textColor = [UIColor colorWithRed:218.0f/255.0f green:247.0f/255.0f blue:220.0f/255.0f alpha:1.0f];
cell.backgroundColor = [UIColor colorWithRed:153.0f/255.0f green:211.0f/255.0f blue:212.0f/255.0f alpha:1.0f];
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
UILabel *contentV = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 230, 44)];
contentV.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:16.0];
contentV.textColor = [UIColor colorWithRed:218.0f/255.0f green:247.0f/255.0f blue:220.0f/255.0f alpha:1.0f];
contentV.backgroundColor = [UIColor colorWithRed:153.0f/255.0f green:211.0f/255.0f blue:212.0f/255.0f alpha:1.0f];
cell.contentView.layoutMargins = UIEdgeInsetsZero;
NSString *username2 = [[transfer objectAtIndex:indexPath.row] valueForKey:#"username"];
NSLog(#"***username***");
NSLog(username2);
contentV.text = username2;
[cell.contentView addSubview:contentV];
return cell;
}
else {
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.textLabel.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size:16.0];
cell.textLabel.textColor = [UIColor colorWithRed:153.0f/255.0f green:211.0f/255.0f blue:212.0f/255.0f alpha:1.0f];
cell.backgroundColor = [UIColor colorWithRed:218.0f/255.0f green:247.0f/255.0f blue:220.0f/255.0f alpha:1.0f];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
NSString *matchAmount = [[transfer objectAtIndex:indexPath.row] valueForKey:#"matches"];
NSLog(#"***matchamount***");
NSLog(matchAmount);
cell.textLabel.text = matchAmount;
return cell;
}
}
Instead of having two separate arrays and going trough the trouble of sorting one of them directly and try to figure out which entries of the other correspond to which in the sorted one, you should instead keep the paired entries of both arrays together in one entity (dictionary or instance of a custom class), and group those in your (single) array:
The actual property names etc. will vary for your code, but the general idea is like this:
self.entries = [NSMutableArray new];
for (int i=0; i < userNameArray.count; i++){
NSMutableDictionary* entry = [NSMutableDictionary new];
entry["userName"] = [userNameArray objectAtIndex: i];
entry["score" ] = [scoreArray objectAtIndex: i];
// ^ TODO: Make sure scoreArray has at least as many elements
// as userNameArray!
[self.entries addObject: entry];
}
self.entries = [self.entries sortedArrayUsingComparator:^NSComparisonResult(NSDictionary* a, NSDictionary* b) {
NSDate *first = [a objectForKey:"score"];
NSDate *second = [b objectForKey:"score"];
return [first compare:second];
}];
// (...)
UITableViewCell* tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath}) indexPath
{
NSDictionary* entry = [self.entries objectAtIndex: indexPath.row];
if (tableView == self.userNameTableView) {
// (dequeue user cell...)
cell.titleLabel.text = [entry objectForKey: "userName"];
return cell
}
else{
// (dequeue score cell...)
cell.titleLabel.text = [entry objectForKey: "score"];
return cell
}
}
Credit goes to NicolasMiari for helping me figure most of this out. Something weird was happening with the way the comparison was being made - and it was producing an unsorted result. This is how I sorted:
NSSortDescriptor * descriptor = [[NSSortDescriptor alloc] initWithKey:#"matches" ascending:NO selector:#selector(localizedStandardCompare:)];
NSArray *entrieshold = [entries sortedArrayUsingDescriptors:#[descriptor]];
transfer = [entrieshold copy];
It seemed like the most important thing for me was selector:#selector(localizedStandardCompare:). My use of copy also may be important...but I don't think so.
In viewDidLoad I add
[super viewDidLoad];
if ([[API sharedInstance] isAuthorized]) {
[self userInfo];
}
then
-(void)userInfo{
API* apiUser = [API sharedInstance];
//load the caption of the selected photo
[apiUser commandWithParams: [NSMutableDictionary dictionaryWithObjectsAndKeys:#"get_user_data", #"command", nil] onCompletion:^(NSDictionary *json) {
//got stream
NSArray* list = [json objectForKey:#"result"];
NSDictionary* userInfo = [list objectAtIndex:0];
name = [NSString stringWithFormat:#"%# %#",[userInfo objectForKey:#"name"], [userInfo objectForKey:#"surname"]];
}];
}
finally cell.textLabel.text and cell.textLabel.font got nothing, text is the same as in storyboard and font is default
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [self.menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (indexPath.row == 0) {
if (name != nil) {
cell.textLabel.text = name;
}
cell.contentView.backgroundColor = [UIColor colorWithRed:0.8 green:0.0 blue:0.03 alpha:1.0];
UIFont *myfontTop = [ UIFont fontWithName:#"myFont" size:IS_PAD?17:11];
cell.detailTextLabel.font = myfontTop;
cell.textLabel.textColor = [UIColor blueColor];
} else {
UIFont *myfont = [ UIFont fontWithName:#"myFont" size:IS_PAD?17:11];
cell.contentView.backgroundColor = [UIColor grayColor];
cell.textLabel.font = myfont;
}
return cell;
}
Does anyone know how to resolve the problem?
I have an existing UITableView that lists a number of cafes in the area. The data for each cafe is being pulled from a MySQL database. When a user clicks on a cafe (cell), it brings a user to a detail view. Currently, users can "Favorite" a cafe by clicking on the star image in each cell (this adds the favorited cell to FavoritesTableView). However, I want users to be able to add a cafe to the FavoritesTableView from the DetailView as well (in other words, "favorite" a cafe from the DetailView). Does anyone know how I would implement this?
Right now, I have the star button in place in my DetailView.m (cafe details):
- (IBAction)buttonpressed:(UIButton *)fave {
if (!checked) {
[checkedButton setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
checked = YES;
}
else if (checked) {
[checkedButton setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
checked = NO;
}
}
ViewController.m (cafes tableview)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strainTableIdentifier = #"StrainTableCell";
StrainTableCell *cell = (StrainTableCell *)[tableView dequeueReusableCellWithIdentifier:strainTableIdentifier];
if (cell == nil)
cell = [[StrainTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strainTableIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"StrainTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
if (tableView == self.searchDisplayController.searchResultsTableView) {
NSLog(#"Using the search results");
cell.titleLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
NSLog(#"%#", searchResults);
} else {
NSLog(#"Using the FULL LIST!!");
cell.titleLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.descriptionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Description"];
cell.ratingLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Rating"];
cell.ailmentLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ailment"];
cell.actionLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Action"];
cell.ingestLabel.text = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Ingestion"];
}
NSMutableDictionary *item = [Strains objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:#"text"];
[item setObject:cell forKey:#"StrainTableCell"];
BOOL checked = [[item objectForKey:#"checked"] boolValue];
NSLog(#"%i",checked);
UIImage *image = (checked) ? [UIImage imageNamed:#"checked.png"] : [UIImage imageNamed:#"unchecked.png"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];
[button addTarget:self action:#selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
return cell;
}
- (void)checkButtonTapped:(id)sender event:(id)event
{
NSLog(#"made it here and event is %#",event);
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.StrainTableView];
NSIndexPath * indexPath ;
indexPath = [self.StrainTableView indexPathForRowAtPoint: currentTouchPosition];
NSLog(#"indexpath is below");
NSLog(#"%#",indexPath);
if (indexPath != Nil)
{
NSMutableDictionary *item = [Strains objectAtIndex:indexPath.row];
BOOL isItChecked = [[item objectForKey:#"checked"] boolValue];
NSMutableArray *quickArray = [[NSMutableArray alloc] initWithArray:Strains];
[quickArray replaceObjectAtIndex:indexPath.row withObject:item];
[item setObject:[NSNumber numberWithBool:!isItChecked] forKey:#"checked"];
Strains = [quickArray copy];
[StrainTableView reloadData];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
StrainDetailViewController *detailViewController = [[StrainDetailViewController alloc] initWithNibName:#"StrainDetailViewController" bundle:nil]; if ([searchResults count]) {
detailViewController.title = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [searchResults objectAtIndex:indexPath.row];
} else {
detailViewController.title = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
detailViewController.strainDetail = [Strains objectAtIndex:indexPath.row];
NSLog(#"%#", Strains);
}
[self.navigationController pushViewController:detailViewController animated:YES];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"strains"] != Nil) {
NSData *dataSave = [[NSUserDefaults standardUserDefaults] objectForKey:#"strains"];
Strains = [NSKeyedUnarchiver unarchiveObjectWithData:dataSave];
}
if (favoritesArray == Nil) {
favoritesArray = [[NSMutableSet alloc] init];
}
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"favorites"] != Nil) {
NSData *dataSave = [[NSUserDefaults standardUserDefaults] objectForKey:#"favorites"];
favoritesArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataSave];
}
I'm just not sure what sort of code I would add to this in order to make the "Checked" button add the selected cell from UITableView to FavoritesTableView.
Hope this made sense. Any ideas?
From a maintainability stand point, the approach I generally take might not be the best. However, from an implementation stand point, it's very easy. I pass a reference to my object (in your case, the object for the table view that was selected) to the details view. From the details view, I can update that object by switching the flag. Since this object is the same object as the table view, updating it will also update the table view (you may have to redraw the table view cell). Last, I update the database from the details view.
Edit
So in your code, it would look like this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
StrainDetailViewController *detailViewController = [[StrainDetailViewController alloc] initWithNibName:#"StrainDetailViewController" bundle:nil]; if ([searchResults count]) {
detailViewController.title = [[searchResults objectAtIndex:indexPath.row] objectForKey:#"Title"];
//YOU'RE ALREADY DOING IT :)
detailViewController.strainDetail = [searchResults objectAtIndex:indexPath.row];
} else {
detailViewController.title = [[Strains objectAtIndex:indexPath.row] objectForKey:#"Title"];
//YOU'RE ALREADY DOING IT :)
detailViewController.strainDetail = [Strains objectAtIndex:indexPath.row];
NSLog(#"%#", Strains);
}
[self.navigationController pushViewController:detailViewController animated:YES];
}
You're already sending a reference to the details view! This makes things easy. In your details view, whenever someone favorites a strain, set the favorite flag for the strainDetail object. This will also update the strainDetail object in the table view. It works like this because you're passing a reference (also referred to as a pointer) to the detail view. In other words, both of your strainDetail objects, aren't objects but pointers to a memory address. If you update either strainDetail, the the memory address for both strainDetail gets changed. Not the strainDetail pointer itself. Here's an link for further explanation https://softwareengineering.stackexchange.com/questions/17898/whats-a-nice-explanation-for-pointers
So your Details view handler will look something like this
- (IBAction)buttonpressed:(UIButton *)fave {
if (!checked) {
[checkedButton setImage:[UIImage imageNamed:#"checked.png"] forState:UIControlStateNormal];
checked = YES;
}
else if (checked) {
[checkedButton setImage:[UIImage imageNamed:#"unchecked.png"] forState:UIControlStateNormal];
checked = NO;
}
//updates in both the detail view and the table view
BOOL isItChecked = [[self.strainDetail objectForKey:#"checked"] boolValue];
[self.strainDetail setObject:[NSNumber numberWithBool:checked] forKey:#"checked"];
}
I also suggest creating a Strain class to hold all of your strain data. Working with dictionaries is not fun, is error prone, and takes forever to figure out what keys you need.
You can save "favorite" state in a global variable/singleton and retrieve it when needed.
This way, even if your table view is deallocated, you won't lose its cells' state.