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.
Related
enter code here[youtube picture of the same code][1]I keep getting an error with my code where it says
"unexpected "#" in program and also missing "#end"
If you look at the code below the #end is there but however much I retype it the answer is the same "missing #end"
Here is the full code
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController ()
#end
#implementation MasterViewController
-(NSMutableArray *) objects
{
if (!_objects){
_objects =[[NSMutableArray alloc]init];
}
return _objects;
}
-(NSMutableArray *) results
{
if (!_results) {
_results =[[NSMutableArray alloc]init];
}
return _results;
}
-(void)viewDidLoad
{
[super viewDidLoad];
[self.objects addObject:#"Tabebuia yellow"];
[self.objects addObject:#"Prunus armeniaca"];
[self.objects addObject:#"Tabebuia rosea"];
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void) searchThroughData
{
self.results= nil;
NSPredicate * resultsPredicate = [NSPredicate predicateWithFormat:#"SELF contains [search]%#", self.searchBar.text];
self. results = [[ self.objects filteredArrayUsingPredicate:resultsPredicate]mutableCopy];
}
-(void) searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self searchThroughData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.tableView)
{
return self.objects.count;
}else{
[self searchThroughData];
return self.results.count;
}
}
-(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];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (tableView == self.tableView){
cell.textLabel.text = self.objects[indexPath.row];
} else {
cell.textLabel.text = self.results[indexPath.row];
}
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (self.searchController.isActive)
{
[self performSegueWithIdentifier:#"Showdetail" sender:self];
}
-(void) PrepareForSegue:(UIStoryboardSegue *) segue sender:(id) sender
if ([[ segue identifier] isEqualToString:#"ShowDetail"]) {
NSString *object = nil;
NSIndexPath *Indexpath = nil;
if (self.UISearchController.isActive)
{UISearchController
Indexpath = [[ self.searchController searchResultsTableView]indexPathForSelectedRow];
object = self.results [Indexpath.row];
}else{
Indexpath = [self.tableView indexPathForSelectedRow];
object = [[self.objects [Indexpath.row];
[segue destinationViewController] setDetailLabelContents:object];
}}
#end
You have no closing } at the end of the prepareForSegue:sender: method. Formatting and indenting properly makes this clear.
You have code just floating outside of a method (the lines before the tableView:didSelectRowAtIndexPath: method.
There needs to be a proper pairing of { and } and code needs to be inside methods or functions.
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.)
I am getting this error and my search function does nothing when the user starts typing a query( XCODE 5.1).
I dont know how the -webView is related to this error as I have not used webView in these files. Any advice would be appreciated. Thank you.
OrdersViewController.h
#import <UIKit/UIKit.h>
#interface OrdersViewController : UITableViewController <UISearchBarDelegate>
//NSmurray is set because we want to edit/move items as well (this will be implemented later)
#property (nonatomic, strong) NSMutableArray *jsonParseArray;
#property (nonatomic, strong) NSMutableArray *ordersArray;
#property (strong, nonatomic) IBOutlet UISearchBar *searchOrders;
#property (nonatomic, strong ) NSMutableArray *orderSearchResults;
#pragma mark -
#pragma mark Class Methods
-(void) retrieveOrderData;
#end
OrdersViewController.m
#import "OrdersViewController.h"
#import "Order.h"
#import "OrderDetailViewController.h"
#define getDataURL #"http://gkhns-macbook-pro.local/gj-3.php"
#interface OrdersViewController ()
#end
#implementation OrdersViewController
#synthesize jsonParseArray, ordersArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
//
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.title = #"ORDERS";
[self retrieveOrderData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)searchThroughOrders {
self.orderSearchResults = nil;
//gettig the text that is entered in the search bar and it creates nspredicated self containes the search and this text will be replaced by search field
NSPredicate *orderResultsPredicate = [NSPredicate predicateWithFormat:#"SELF contains [search] %#", self.searchOrders.text];
//filtering the predicate that is set before
self.orderSearchResults = [[self.ordersArray filteredArrayUsingPredicate:orderResultsPredicate] mutableCopy];
}
//detect when the user typed in the search
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self searchThroughOrders];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//are we in regular table view or search display view? Lets check that
if (tableView == self.tableView)
{
return ordersArray.count;
}
else{
[self searchThroughOrders];
// Return the number of rows in the section.
return self.orderSearchResults.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"OrderCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle=UITableViewCellStyleDefault;
}
if (tableView== self.tableView)
// Configure the cell...
{Order *orderObject;
orderObject = [ordersArray objectAtIndex:indexPath.row];
cell.textLabel.text=orderObject.order_id;
cell.detailTextLabel.text=orderObject.firstname;
}
else
{
cell.textLabel.text = self.orderSearchResults [indexPath.row];
}
//accessory
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Navigation
//In a story board-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([[segue identifier] isEqualToString:#"pushOrderDetailView"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Order* object = [ordersArray objectAtIndex:indexPath.row];
[[segue destinationViewController] getOrder:object];
}
}
#pragma mark -
#pragma mark Class Methods
-(void) retrieveOrderData{
NSURL * url = [NSURL URLWithString:getDataURL];
NSData * data = [NSData dataWithContentsOfURL:url];
jsonParseArray=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
//orders array
ordersArray= [[NSMutableArray alloc]init];
//loop through the jason array
for (int i=0; i<jsonParseArray.count; i++)
{
//create the order object
NSString *oId = [[jsonParseArray objectAtIndex:i] objectForKey:#"order_id"];
NSString *eMail = [[jsonParseArray objectAtIndex:i] objectForKey:#"email"];
NSString *fName = [[jsonParseArray objectAtIndex:i] objectForKey:#"firstname"];
NSString *lName = [[jsonParseArray objectAtIndex:i] objectForKey:#"lastname"];
NSString *sName = [[jsonParseArray objectAtIndex:i] objectForKey:#"store_name"];
NSString *iPrefix = [[jsonParseArray objectAtIndex:i] objectForKey:#"invoice_prefix"];
NSString *pAddress1 = [[jsonParseArray objectAtIndex:i] objectForKey:#"payment_address_1"];
NSString *sPaymentAddress2 = [[jsonParseArray objectAtIndex:i] objectForKey:#"payment_address_2"];
//add order to orders array
[ordersArray addObject:[[Order alloc]initWithOrderId: (NSString *)oId andInvoicePrefix: (NSString*)iPrefix andStoreName:(NSString*)sName andFirstName:(NSString*)fName andLastName:(NSString*)lName andEmail:(NSString*)eMail andPaymentAddress1:(NSString*)pAddress1 andPaymentAddress2:(NSString*)sPaymentAddress2]];
}
//reload the view
[self.tableView reloadData];
}
#end
I was using searchbar only instead of search bar and the search display controller which may have caused this issue.
Also done a few changes to the searchdisplay controller implementation below which fixed the issue.
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self searchThroughOrders:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
-(void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView{
[tableView registerClass:[CustomOrdersCell class] forCellReuseIdentifier:#"OrderCell"];
}
-(void)searchThroughOrders:(NSString *)searchText scope:(NSString*)scope {
//getting the text that is entered in the search bar and it creates nspredicated self containes the search and this text will be replaced by search field
NSPredicate *orderResultsPredicate = [NSPredicate predicateWithFormat:#"order_id contains[c] %#", searchText];
//filtering the predicate that is set before
_orderSearchResults = [ordersArray filteredArrayUsingPredicate:orderResultsPredicate];
}
This is a simple class that extended UITableViewController, there's only one section total 5 rows. but when launch app, only show 2 record, when pressed the button, it will show more records with text field.
but, press simple button and press detail button , i found the order in table is wrong.
I don't know what happen, so can help me to solve this problem?
Many thanks
- (void)viewDidLoad
{
[super viewDidLoad];
tempSimpleAry = [#[#"simple1",#"simple2"] mutableCopy];
tempDetailAry = [#[#"detail A",#"detail B",#"detail C"] mutableCopy];
dataAry = [[NSMutableArray alloc]init];
[dataAry addObjectsFromArray:tempSimpleAry];
isExpanded = NO;
}
-(void)dealloc{
[super dealloc];
tempSimpleAry = nil;
tempDetailAry = nil;
dataAry = nil;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (BOOL)textFieldShouldReturn:(UITextField *)aTextField {
[aTextField resignFirstResponder];
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return dataAry.count+1;
}
static NSString *BasicCellIdentifier = #"BasicCell";
static NSString *MyCellIdentifier = #"MyCell";
static NSString *LastCellIdentifier = #"LastCell";
UITableViewCell *Lastcell = nil;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int row = indexPath.row;
if(indexPath.row<tempSimpleAry.count){
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:BasicCellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [[NSString alloc]initWithFormat:#"%# %d", [dataAry objectAtIndex:row], row];
return cell;
}else if(indexPath.row < dataAry.count){
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyCellIdentifier forIndexPath:indexPath];
cell.myTitleLabel.text = [[NSString alloc]initWithFormat:#"%# %d", [dataAry objectAtIndex:row], row];
cell.myTextField.placeholder = [[NSString alloc]initWithFormat:#"%# %d", [dataAry objectAtIndex:row], row];
NSLog(#"MyTableViewCell - myTitlelabel = %#, mytextfield tag = %d, text = %#", cell.myTitleLabel.text, cell.myTextField.tag,cell.myTextField.text);
cell.myTextField.tag =100+indexPath.row;
return cell;
}else{
Lastcell = [tableView dequeueReusableCellWithIdentifier:#"LastCell" forIndexPath:indexPath];
Lastcell.textLabel.text = #"Detail";
return Lastcell;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[currentEditingTextField resignFirstResponder];
NSMutableArray *tmpAry = [[NSMutableArray alloc]init];
if(indexPath.row == dataAry.count){
if(isExpanded){
int idx = dataAry.count-1;
for(int i=0; i<tempDetailAry.count;i++){
NSIndexPath *idxPaths = [NSIndexPath indexPathForRow:idx-i inSection:0] ;
[tmpAry addObject:idxPaths];
[dataAry removeLastObject];
}
[tableView deleteRowsAtIndexPaths:tmpAry withRowAnimation:UITableViewRowAnimationFade];
}else{
int idx = tempSimpleAry.count;
for(int i=0; i<tempDetailAry.count;i++){
NSIndexPath *idxPaths = [NSIndexPath indexPathForRow:idx+i inSection:0] ;
[tmpAry addObject:idxPaths];
[dataAry insertObject:[tempDetailAry objectAtIndex:i] atIndex:idx+i];
}
[tableView insertRowsAtIndexPaths:tmpAry withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView beginUpdates];
[self.tableView endUpdates];
isExpanded = !isExpanded;
if(!isExpanded)
Lastcell.textLabel.text = #"Detail";
else
Lastcell.textLabel.text = #"Simple";
}
}
It is because the cells are cached with cellIdentifier.
When you press Simple, you delete cells by the sequence, 'detail C 4', 'detail B 3', 'detail A 2'. So the 'detail C 4' cell is pushed into the cache queue first, then 'detail B 3' cell, finally 'detail C 2' cell.
Then you press Detail, the tableView query the cache queue one by one. Because the 'detail C 4' cell is at the front, it is popped first. So u use the cell with 'aa' in the textField, and then you set the cell.myTitleLabel.text and cell.myTextField.placeholder, but you don't set the cell.myTextField.text, which is 'aa'. Finally, the cell became 'detail A 2' with text 'aa' in the textField.
The same with the other two cells.
Is the above clear for you ?
It seems that u are only changing the textfield's place holder not its text, You should also save the textfield's text into an array and set it in cellForRowAtIndexPath!
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
}
}