Hide tableview sections on tap gesture of section header - objective-c

I want to hide the NSArrays (menuItems, about, and charting) on the click for the specific section header for the tableview cell arrays. I got the section header to highlight and de-highlight depending on tap gesture recognizer count but I can not get the tableview cells to hide when that specific section header is clicked. Can someone please help? Thank you! Here is my .m code. My GCF float method is located at the bottom of the .m.
#interface SidebarTableViewController ()
#end
#implementation SidebarTableViewController {
NSArray *menuItems;
NSArray *about;
NSArray *charting;
}
- (void)viewDidLoad {
[super viewDidLoad];
menuItems = #[#"Home",#"Field Goal", #"Punt", #"Kick Off", #"Snapper", #"Punter"];
about = #[#"Home",#"About Us", #"Tutorial"];
charting = #[#"Home",#"Charting"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (indexPath.section==0) {
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
else if(indexPath.section==1) {
NSString *CellIdentifier2 = [charting objectAtIndex:indexPath.row];
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2 forIndexPath:indexPath];
return cell2;
}
else {
NSString *CellIdentifier1 = [about objectAtIndex:indexPath.row];
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1 forIndexPath:indexPath];
return cell1;
}
}
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[menuItems objectAtIndex:indexPath.row] capitalizedString];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3 ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section==0)
{
return [menuItems count];
}
else if(section==1)
{
return [charting count];
}
else{
return [about count];
}
}
- (UIView*) tableView: (UITableView*) tableView viewForHeaderInSection: (NSInteger) section
{
UILabel *headerLabel = [[UILabel alloc]init];
headerLabel.tag = section;
headerLabel.userInteractionEnabled = YES;
headerLabel.backgroundColor = [UIColor grayColor];
if(section == 0){
headerLabel.text = [NSString stringWithFormat:#"Timers Without Charting"];
}
else if(section==1)
{
headerLabel.text = [NSString stringWithFormat:#"Charting with Timers"];
}
else{
headerLabel.text = [NSString stringWithFormat:#"About Us/Tutorial"];
}
headerLabel.frame = CGRectMake(0, 0, tableView.tableHeaderView.frame.size.width, tableView.tableHeaderView.frame.size.height);
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(catchHeaderGesture:)];
tapGesture.cancelsTouchesInView = NO;
[headerLabel addGestureRecognizer:tapGesture];
return headerLabel;
//return nil;
}
-(void)catchHeaderGesture:(UIGestureRecognizer*)sender
{
border ++;
if (border == 1)
{
UILabel *caughtLabel = (UILabel*)sender.view;
caughtLabel.layer.borderColor = [UIColor yellowColor].CGColor;
caughtLabel.layer.borderWidth = 2;
}
if (border == 2 )
{
UILabel *caughtLabel = (UILabel*)sender.view;
caughtLabel.layer.borderColor = [UIColor clearColor].CGColor;
caughtLabel.layer.borderWidth = 2;
border = 0;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
border ++;
if (border == 1)
{
UITableViewCell* cell = [menuItems objectAtIndex:indexPath.row];
cell.hidden = YES;
return 40.0;
}
if (border == 2 )
{ border = 0;
UITableViewCell* cell = [menuItems objectAtIndex:indexPath.row];
cell.hidden = YES;
}
return 0;
}
#end

You need a few couple things to make this work.
section headers that respond to taps.
a method for expanding or collapsing a section.
some way to track which sections are collapsed.
The first is trivial. Return a UIView for the header, and attach a UITapGestureRecognizer to it. You'll need a method to figure out which section it is. You can use the tag property, or you can store the views in an NSMutableArray.
In tableView:numberOfRowsInSection: you return 0 if the section is collapsed, or the actual number, if not.
In the handler for the gesture recognizer, you toggle the collapsed/expanded state, and then you call `[self.tableView reloadSections:withRowAnimation:] to update the visuals.
(I do see in your posted code that you already handle part of this.)

Related

I need to implement the expandable tableView cell in ios 8

In my project I need to implement the UITableview with some of the tableView cells are expandable and some of them are independent. If it is expandable cell need to indicate the '+' symbol.enter image description here. Can any one please help me out
I have created a small demo,
https://github.com/haripalwagh/ExpandableTableviewCell
Screenshot 1 : Before expanding a cell
Screenshot 2 : After expanding a cell
#interface ViewController ()
<UITableViewDataSource,
UITableViewDelegate>
{
UITableView *tblView;
NSArray *cell0SubMenuItemsArray;
BOOL isSection0Cell0Expanded;
}
#end
#implementation ViewController
# pragma mark - View Life Cycle
- (void)viewDidLoad
{
[super viewDidLoad];
tblView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
tblView.backgroundColor = [UIColor clearColor];
tblView.delegate = self;
tblView.dataSource = self;
tblView.allowsSelection = YES;
tblView.scrollEnabled = YES;
tblView.alwaysBounceVertical = YES;
[self.view addSubview:tblView];
cell0SubMenuItemsArray = #[#"First Static Menu Item", #"Second Static Menu Item", #"Third Static Menu Item"];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.view setNeedsLayout];
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self updateViewDimensions];
}
- (void)updateViewDimensions
{
tblView.frame = CGRectMake(0, 40, 320, 550);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
# pragma mark - UITableView Delegate and Datasource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
{
int cellCount = 2; // Default count - if not a single cell is expanded
if (isSection0Cell0Expanded)
{
cellCount += [cell0SubMenuItemsArray count];
}
return cellCount;
}
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCellId = #"CellId";
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strCellId];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (indexPath.section == 0)
{
if (indexPath.row == 0)
{
cell.textLabel.text = #"Expandable Cell";
UIImageView *accessoryImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
if (isSection0Cell0Expanded) // Set accessory view according to cell state - EXPANDED / NOT EXPANDED
{
accessoryImageView.image = [UIImage imageNamed:#"Minus.png"];
cell.detailTextLabel.text = #"Status : Expanded";
}
else
{
accessoryImageView.image = [UIImage imageNamed:#"Plus.png"];
cell.detailTextLabel.text = #"Status : Not Expanded";
}
cell.accessoryView = accessoryImageView;
}
else
{
if (isSection0Cell0Expanded && [cell0SubMenuItemsArray count] >= indexPath.row) // Check Expanded status and do the necessary changes
{
cell.textLabel.text = [NSString stringWithFormat:#"%#", [cell0SubMenuItemsArray objectAtIndex:indexPath.row - 1]];
}
else
{
cell.textLabel.text = #"Static Cell";
}
}
}
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
{
// Change status of a cell reload table
isSection0Cell0Expanded = !isSection0Cell0Expanded;
[tblView reloadData];
}
}
You have to manage like this for every expandable cell.
Hope this will help you..
Try this control: https://github.com/jonasman/JNExpandableTableView
It supports what you say. Tapping on a cell expands it.

UITableViewController with multiple segues going to the wrong view

So I'm completely stumped here. I'm using xcode 5 and I have a table view with 2 segues. I tried to set the segues originally with two different prototype cells, but that didn't work. So I now have both segues set at the UITableViewController. It seems like whichever segue I created last is the one it goes to. I'm not getting any errors and when I step through the code, it fires on the correct line to execute the segue.
This seems to execute perfectly every time but it just doesn't go to the correct view.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if([currentTableViewType isEqualToString:#"feedbackOnly"]){
// hits this line correctly
[self performSegueWithIdentifier:#"ShowSendFeedback" sender:indexPath];
} else {
// hits this line correctly
[self performSegueWithIdentifier:#"ShowTicketDetails" sender:indexPath];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(NSIndexPath *)selectedIndexPath {
if ([[segue identifier] isEqualToString:#"ShowTicketDetails"])
{
TicketDetailsViewController *tdv = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
tdv.tPriority = currentTicket.ticketPriority;
tdv.tId = currentTicket.ticketId;
tdv.tStatus = currentTicket.ticketStatus;
}
if ([[segue identifier] isEqualToString:#"ShowSendFeedback"]){
FeedbackViewController *fvc = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
fvc.tPriority = currentTicket.ticketPriority;
fvc.tId = currentTicket.ticketId;
fvc.tStatus = currentTicket.ticketStatus;
}
}
To be thorough, I've included my entire controller that has the issue.
#import "TicketsViewController.h"
#interface TicketsViewController ()
#end
#implementation TicketsViewController
#synthesize json, ticketsArray, ticketsTableView, currentTableViewType;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Tickets";
AppDataClass *appData=[AppDataClass getInstance];
currentTableViewType = appData.tableViewType;
[self retrieveData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (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.
return ticketsArray.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if([currentTableViewType isEqualToString:#"feedbackOnly"]){
return #"Requires Feedback";
} else {
return #"Issues";
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
Ticket * currentTicket = [ticketsArray objectAtIndex:indexPath.row];
cell.textLabel.text = currentTicket.ticketName;
cell.detailTextLabel.text = currentTicket.ticketAddress;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if([currentTicket.ticketPriority.lowercaseString isEqualToString:#"high"]) {
cell.imageView.image = [UIImage imageNamed:#"alert.png"];
if([indexPath row] % 2) [cell setBackgroundColor:[UIColor lightGrayColor]];
}
return cell;
}
#pragma mark - Methods
- (void)retrieveData
{
// NSURL * url = [NSURL URLWithString:getDataURL];
// NSData * data = [NSData dataWithContentsOfURL:url];
AppDataClass *appData=[AppDataClass getInstance];
NSString *args = #"userid=%#&authid=%#";
NSString *values=[NSString stringWithFormat:args, appData.userId, appData.authId];
json = [appData getPostData:appData.URL_LIST_TICKETS:values];
ticketsArray = [[NSMutableArray alloc] init];
// segeue names
// allTickets
// feedbackOnly
for(int i=0; i<json.count; i++){
NSString * tId = [[json objectAtIndex:i] objectForKey:#"id"];
NSString * tName = [[json objectAtIndex:i] objectForKey:#"name"];
NSString * tPriority = [[json objectAtIndex:i] objectForKey:#"priority"];
Ticket * myTicket = [[Ticket alloc] initWithTicketId:tId andTicketName:tName andTicketPriority:tPriority];
[ticketsArray addObject:myTicket];
}
[self.ticketsTableView reloadData];
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if([currentTableViewType isEqualToString:#"feedbackOnly"]){
[self performSegueWithIdentifier:#"ShowSendFeedback" sender:indexPath];
} else {
[self performSegueWithIdentifier:#"ShowTicketDetails" sender:indexPath];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(NSIndexPath *)selectedIndexPath {
if ([[segue identifier] isEqualToString:#"ShowTicketDetails"])
{
TicketDetailsViewController *tdv = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
tdv.tPriority = currentTicket.ticketPriority;
tdv.tId = currentTicket.ticketId;
tdv.tStatus = currentTicket.ticketStatus;
}
if ([[segue identifier] isEqualToString:#"ShowSendFeedback"]){
FeedbackViewController *fvc = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
long row = [myIndexPath row];
Ticket * currentTicket = [ticketsArray objectAtIndex:row];
fvc.tPriority = currentTicket.ticketPriority;
fvc.tId = currentTicket.ticketId;
fvc.tStatus = currentTicket.ticketStatus;
}
}
#end
Ok... so it seems to be a bug in XCode. I had originally copied the 2nd ViewController that I was trying to segue to and changed the class of it as well as some of the view components. I figured StoryBoard would be smart enough to reassign this view as its own. I was wrong. XCode didn't seem to like that. Starting from scratch with a new ViewController seems to fix everything and the segues are working correctly now. The exact same code works.
So if anyone is having this issue, make sure you didn't copy and paste a ViewController that you are trying to segue to. This will save you hours of headaches :-)
It probably had a reference to the same ViewController which is why whatever the last segue I setup was the only one working.

Display centered 200x150 Image in a UITableViewCell

I need to display a centered 200x150 image in a UITableViewCell. I was able to add the image to a standard cell type (it shrunk it to fit - that wasn't working). I then tried redrawing it by setting the bounds and frame for the image (this caused overlap between my image and the other rows).
I have a custom class inheriting from UITableViewCell:
#import "WCPictureViewCell.h"
#implementation WCPictureViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.frame = CGRectMake(5,5,210,160);
self.bounds = CGRectMake(5,5,210,160);
self.imageView.frame = CGRectMake(0,0,200,150);
self.imageView.bounds = CGRectMake(0,0,200,150);
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
This code produces picture overlap with the rest of my table:
Here is my tableView:cellForRowAtIndexPath: method in my controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if(cellPropertyMap>0) {
static NSString *CellIdentifier = #"DetailCell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
[[cell textLabel] setText: (NSString *)[[self displayLabels]objectAtIndex:cellPropertyMap]];
[[cell detailTextLabel] setText: (NSString *)[[self displayData]objectAtIndex:cellPropertyMap++]];
} else {
static NSString *CellIdentifier = #"PictureCell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//if(cell == nil) {
//}
// Configure the cell...
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: [cat friendlyURLPath]]];
cell.imageView.image = [UIImage imageWithData: imageData];
cellPropertyMap++;
return cell;
}
return cell;
}
How do I force my table cells to respect eachother's sizes and not overlap? How do I get my image to center?
You need to use
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath)
{
// add logic to determine if this indexPath is an image...
if (indexPath.row == 0) // first row in a section is an image?
return (150.0f); // this row is an image
else
return (44.0f); // this is a standard data row
}
to return the correct height of your TableView row.
Second step is to get the image to center, there are various techniques. Try
UIImageView *yourImage = ...;
// set frame and auto-resizing mask
yourImage.frame = CGRectMake(tableView.bounds.size.width / 2) - (yourImage.size.width / 2), 0, yourImage.size.width, yourImage.size.height);
yourImage.autoResizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
// add UIImage to the cell contentView
[cell.contentView addSubview:yourImage];
don't set the cell.imageView property, which defines a left justified image in the cell.
Lastly, and off-topic from your question, you should really consider lazy-loading the images, using initWithContentsOfURL on the UI thread will not yield a good user experience.

Disclosure Buttons, icons don't display in FirstLevelController

I have written the following code for a FirstLevelController implementation file, but the Disclosure Buttons, icons don't display in the view. Have checked the code, but can't figure out what's wrong.
FirstLevelController.m:
#import "BiDFirstLevelController.h"
#import "BidSecondLevelController.h"
#import "BiDDisclosureButtonController.h"
#implementation BiDFirstLevelController
#synthesize controllers;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"First Level";
NSMutableArray *array = [[NSMutableArray alloc]init];
// Disclosure button
BiDDisclosureButtonController *disclosureButtonController = [[BiDDisclosureButtonController alloc]initWithStyle:UITableViewStylePlain];
disclosureButtonController.title = #"Disclosure Buttons";
disclosureButtonController.rowImage = [UIImage imageNamed:#"disclosureButtonControllerIcon.png"];
[array addObject:disclosureButtonController];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.controllers = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.controllers count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstLevelCell = #"FirstLevelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FirstLevelCell];
}
// Configure the cell...
NSUInteger row = [indexPath row];
BiDSecondLevelController *controller = [controllers objectAtIndex:row];
cell.textLabel.text = controller.title;
cell.imageView.image = controller.rowImage;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
BiDSecondLevelController *nextController = [self.controllers objectAtIndex:row];
[self.navigationController pushViewController:nextController animated:YES];
}
#end
Your implementation of numberOfSectionsInTableView: returns 0, which means the table view should always be empty. Since returning 0 from this method doesn't make sense, I guess it's a typo.

cellForRowAtIndexPath returns null but really need similar method

I have a UITableView in my UITableViewController (lol, obviously) but I need to get a cell at a given index inside the - (void)viewWillAppear:(BOOL)animated method.
Now, my cells are static and I create them in the interface builder. If I call
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:previously_selected_cell.integerValue inSection:0]];
it returns null for the cell. I only have 3 static cells in 1 sections. I tried both sections 0 and 1 and both return null.
Currently I have removed the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method because if I add it, it will clear the UITableView of all my static cells.
Is there a method I can call in - (void)viewWillAppear:(BOOL)animated that will return a cell at a given index?
Thanks in advance!
EDIT: I checked out this stackoverflow question but I'm using static cells without cellForRowAtIndexPath so that question didn't help. :(
EDIT2: I'm trying to set the accessory type of the cell when the view loads. But only on a certain cell, that cell being the one the user selected before he quit the app.
#import "AutoSyncSettings.h"
#import "CDFetchController.h"
#implementation AutoSyncSettings
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
CDFetchController *cdfc = [[CDFetchController alloc] init];
NSFetchedResultsController *results = [cdfc getFetchedResultsControllerWithEntityName:#"SETTINGS"];
NSArray *objects = [results fetchedObjects];
NSNumber *sync_setting;
if(objects.count > 0)
{
NSManagedObject *object = [objects objectAtIndex:0];
sync_setting = [object valueForKey:#"wifi_setting"];
NSLog(#"(Settings)sync_setting: %#",sync_setting);
NSLog(#"(Settings)sync_setting int value: %i",sync_setting.integerValue);
NSLog(#"(Settings)TableView: %#",self.tableView);
//cell is null, even after this.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:wifi_settings.integerValue inSection:0]];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
//cell is still null. WHY OH WHY? :(
objects = nil;
}
cdfc = nil;
results = nil;
objects = nil;
sync_setting = nil;
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
for (int i = 0; i < [tableView numberOfRowsInSection:indexPath.section]; i++)
{
if([[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:indexPath.section]] accessoryType] == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:indexPath.section]].accessoryType = UITableViewCellAccessoryNone;
}
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
CDFetchController *cdfc = [[CDFetchController alloc] init];
NSFetchedResultsController *results = [cdfc getFetchedResultsControllerWithEntityName:#"SETTINGS"];
NSManagedObjectContext *context = [results managedObjectContext];
NSArray *objects = [results fetchedObjects];
if(objects.count > 0)
{
NSManagedObject *object = [objects objectAtIndex:0];
NSNumber *sync_setting = [NSNumber numberWithInt:indexPath.row];
[object setValue:sync_setting forKey:#"sync_interval"];
[object setValue:[NSNumber numberWithInt:0] forKey:#"id"];
[ErrorHandler saveMoc:context];
}
else
{
//INSERT NEW OBJECT
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:#"SETTINGS" inManagedObjectContext:context];
NSNumber *sync_setting = [NSNumber numberWithInt:indexPath.row];
[object setValue:sync_setting forKey:#"sync_interval"];
[object setValue:[NSNumber numberWithInt:0] forKey:#"id"];
[ErrorHandler saveMoc:context];
}
}
#end
I have a project doing exactly this and it works perfectly. However, it doesn't work unless you call [super viewWillAppear:animated] before trying to access the cells in this manner.
The base implementation presumably loads in the cells from the storyboard.
I want to add a checkmark accessory to the previously selected cell,
the previously_selected_cell variable gets stored even if the app
quits/crashes
The way to go will be to control the indexPath in your cellForRowAtIndexPath implementation and act if it's equal to previously_selected_cell.integerValue:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// usual cache lookup, allocation of the cell, etc
if (indexPath.row == previously_selected_cell.integerValue) {
// add checkbox here
} else {
// remove checkbox
}
}