I am trying to create a table view pragmatically(no xib and no storyboards), but the food array isn`t showing up in table view at all. I will post all my code in view controller.
Viewcontroller.h
#interface searchViewController : ViewController<UITextFieldDelegate,UISearchBarDelegate,UITableViewDataSource>{
NSMutableArray * getterms;
}
#property (strong, nonatomic) NSMutableArray* allTableData;
#property (strong, nonatomic) NSMutableArray* filteredTableData;
#property (nonatomic, assign) bool isFiltered;
#property (nonatomic, retain) UITableView *tableView;
Viewcontroller.m
-(void)viewDidLoad{
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(10.0, 10.0, 1000.0, 200.0) style:UITableViewStylePlain];
[self.view addSubview:tableView];
self.tableView.dataSource = self;
allTableData = [[NSMutableArray alloc] initWithObjects:
[[Food alloc] initWithName:#"Steak" andDescription:#"Rare"],
[[Food alloc] initWithName:#"Steak" andDescription:#"Medium"],
[[Food alloc] initWithName:#"Salad" andDescription:#"Caesar"],
[[Food alloc] initWithName:#"Salad" andDescription:#"Bean"],
[[Food alloc] initWithName:#"Fruit" andDescription:#"Apple"],
[[Food alloc] initWithName:#"Potato" andDescription:#"Baked"],
[[Food alloc] initWithName:#"Potato" andDescription:#"Mashed"],
[[Food alloc] initWithName:#"Bread" andDescription:#"White"],
[[Food alloc] initWithName:#"Bread" andDescription:#"Brown"],
[[Food alloc] initWithName:#"Hot Dog" andDescription:#"Beef"],
[[Food alloc] initWithName:#"Hot Dog" andDescription:#"Chicken"],
[[Food alloc] initWithName:#"Hot Dog" andDescription:#"Veggie"],
[[Food alloc] initWithName:#"Pizza" andDescription:#"Pepperonni"],
nil ];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MYCellIdentifier = #"MyCellIdentifier";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:MYCellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:MYCellIdentifier];
Food* food;
if(isFiltered)
food = [filteredTableData objectAtIndex:indexPath.row];
else
food = [allTableData objectAtIndex:indexPath.row];
cell.textLabel.text = food.name;
cell.detailTextLabel.text = food.description;
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int rowCount;
if(self.isFiltered)
rowCount = filteredTableData.count;
else
rowCount = allTableData.count;
return rowCount;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
Looks like you never assign your table view to your controller, add
self.tableView = tableView
as a second line in viewDidLoad
You need to set the tableView's delegate.
From Apple's documentation:
A UITableView object must have an object that acts as a data source and an object that acts as a delegate
Make sure cellForRowAtIndexPath is actually being called (use NSlog or breakpoint to check), if not, you have not set the UITableViewController's tableView to the tableView it is controlling, or you have not set your dataSource Delegate.
Related
I updated my xcode using 6.1 simulator, my app was working fine for 5.1 simulator,
now i am getting the following error :
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UITableViewController loadView] loaded the "MySubscriptionsViewController" nib but didn't get a UITableView.'
my header file:
#import <UIKit/UIKit.h>
#interface MySubscriptionsViewController : UITableViewController{
}
#property (nonatomic,retain) NSString *serverAddress;
#property (nonatomic, retain) UITextField *airportField;
#property (nonatomic, retain) NSMutableArray *airportList;
#property (nonatomic, retain) NSMutableArray *colCode;
#property (nonatomic, retain) NSMutableArray *colAirport;
#property (nonatomic, retain) NSMutableArray *colStartDate;
#property (nonatomic, retain) NSMutableArray *colStartTime;
#property (nonatomic, retain) NSMutableArray *colEndTime;
#property (nonatomic, retain) NSMutableDictionary *tempAirport;
#property (nonatomic,strong) NSDictionary *countryList;
#property (nonatomic,strong) NSArray *countryKeys;
- (IBAction)Meetup:(id)sender;
- (IBAction)ViewBeacon:(id)sender;
-(IBAction)gotoHome:(id)sender;
-( void)beacon:(NSString *)theStr;
#end
my m file:
#import "MySubscriptionsViewController.h"
#import "MybeaconsViewController.h"
#import "SBJsonParser.h"
#import "GridTableViewCell.h"
#import "MeetupViewController.h"
#import "ViewBeaconViewController.h"
#import "DataClass.h"
#import "MemberPanelViewController.h"
#interface MySubscriptionsViewController ()
#end
#implementation MySubscriptionsViewController
#synthesize countryList,countryKeys,serverAddress,airportField,airportList,tempAirport,colStartTime,colEndTime,colStartDate,colAirport,colCode;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0,0);
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
DataClass *obj=[DataClass getInstance];
// serverAddress = #"http://www.cloudnetpk.com/transbeacon_design/services";
NSString *strURL = [NSString stringWithFormat:#"http://www.cloudnetpk.com/transbeacon_design/services/get_my_beacon_subscriptions.php?code=%#",obj.str];
NSLog(#" url => %#",strURL);
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSArray *datos = [parser objectWithString:strResult error:nil];
tempAirport = [[NSMutableDictionary alloc] init];
airportList = [[NSMutableArray alloc] init];
colStartTime = [[NSMutableArray alloc] init];
colEndTime = [[NSMutableArray alloc] init];
colStartDate= [[NSMutableArray alloc] init];
colAirport= [[NSMutableArray alloc] init];
colCode= [[NSMutableArray alloc] init];
countryList = datos;
NSLog(#"beacons count %d",datos.count);
for (int i=0; i<datos.count; i++){
int a=0;
NSString *startDate = [[[datos objectAtIndex:i] objectForKey:#"start_date" ] lowercaseString];
NSString *airPort= [[[datos objectAtIndex:i] objectForKey:#"airport" ] lowercaseString];
NSString *startTime = [[[datos objectAtIndex:i] objectForKey:#"start_time" ] lowercaseString];
NSString *endTime = [[[datos objectAtIndex:i] objectForKey:#"end_time" ] lowercaseString];
NSString *code = [[[datos objectAtIndex:i] objectForKey:#"code" ] lowercaseString];
//NSLog(#" here =>%#",code);
[colStartDate insertObject:startDate atIndex:i ];
[colAirport insertObject:airPort atIndex:i ];
[colStartTime insertObject:startTime atIndex:i ];
[colEndTime insertObject:endTime atIndex:i ];
[colCode insertObject:code atIndex:i];
//[ tempAirport setObject:lcString forKey:lcStringValue];
}
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [countryList count];
}
/*
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell =[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"cell"];
NSString *currentCountryName=[countryKeys objectAtIndex:[indexPath row]];
[[cell textLabel] setText:currentCountryName];
//cell.detailTextLabel.text=#"testing here ";
return cell;
}
*/
-(UITableViewCell *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
static NSString *CellIdentifier = #"SectionHeader";
//UITableViewCell *headerView = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(10,0,300,60)] ;
UIImage *myImage=[UIImage imageNamed:#"top_bar.png"];
UIImageView *imageView =[[UIImageView alloc] initWithImage:myImage];
imageView.frame= CGRectMake(0, 0, 400, 50);
[headerView addSubview:imageView];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(110,3, tableView.bounds.size.width - 170,40)];
label.text = #"Subscriber List";
label.textColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:16];
label.backgroundColor = [UIColor clearColor];
[headerView addSubview:label];
UIButton *circularButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect circularRect = CGRectMake(5.0, 5, 58.0, 32.0);
[circularButton setFrame:circularRect];
[circularButton addTarget:self action:#selector(Meetup:) forControlEvents:UIControlEventTouchUpInside];
UIImage *buttonImage = [UIImage imageNamed:#"back_btn.png"];
[circularButton setImage:buttonImage forState:UIControlStateNormal];
[headerView addSubview:circularButton];
UIButton *homeButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect circularRectHome = CGRectMake(250.0, 5, 58.0, 32.0);
[homeButton setFrame:circularRectHome];
[homeButton addTarget:self action:#selector(gotoHome:) forControlEvents:UIControlEventTouchUpInside];
UIImage *buttonImageHome = [UIImage imageNamed:#"home_btn.png"];
[homeButton setImage:buttonImageHome forState:UIControlStateNormal];
[headerView addSubview:homeButton];
return headerView;
}
-(IBAction)gotoHome:(id)sender{
// redirect
MemberPanelViewController *window =[[MemberPanelViewController alloc]init];
[self presentModalViewController:window animated:YES];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 50;
}
- (IBAction)Meetup:(id)sender{
NSLog(#" button clicked here");
MeetupViewController *window =[[MeetupViewController alloc]init];
[self presentModalViewController:window animated:YES];
}
- (IBAction)ViewBeacon:(id)sender{
ViewBeaconViewController *window=[[ViewBeaconViewController alloc]init];
[self presentModalViewController:window animated:YES];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
GridTableViewCell *cell = (GridTableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[GridTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.lineColor = [UIColor blackColor];
}
// Since we are drawing the lines ourself, we need to know which cell is the top cell in the table so that
// we can draw the line on the top
if (indexPath.row == 0)
cell.topCell = YES;
else
cell.topCell = NO;
// Configure the cell.
//cell.cell1.text = [NSString stringWithFormat:#"%i",indexPath.row];
//cell.cell2.text = [NSString stringWithFormat:#"%i", indexPath.row];
//cell.cell3.text = #"test here text";
cell.cell1.text =[colStartDate objectAtIndex:indexPath.row];
cell.cell2.text =[colAirport objectAtIndex:indexPath.row];
cell.cell3.text =[colStartTime objectAtIndex:indexPath.row];
cell.cell4.text = [colEndTime objectAtIndex:indexPath.row];
NSString *value = [colCode objectAtIndex:indexPath.row];
NSLog(#" value => %#",value);
UIButton *circularButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect circularRect = CGRectMake(260.0, 2, 60.0, 40.0);
[circularButton setFrame:circularRect];
[circularButton addTarget:self action:#selector(beacon:) forControlEvents:UIControlEventTouchUpInside];
circularButton.tag=value;
UIImage *buttonImage = [UIImage imageNamed:#"view.png"];
[circularButton setImage:buttonImage forState:UIControlStateNormal];
[cell.contentView addSubview:circularButton];
return cell;
}
-( void)beacon:(NSString *)theStr{
NSInteger *tid = ((UIControl*)theStr).tag;
NSLog(#" here is parameter %#",tid);
ViewBeaconViewController *window=[[ViewBeaconViewController alloc]init];
// window.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
window.theDataYouWantToPass =tid;
window.lastscreen =#"subscription";
[self presentModalViewController:window animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UITableViewController loadView] loaded the "MySubscriptionsViewController" nib but didn't get a UITableView.' This error Ocurce becouse some bellow issue.
I think the problem is because you are subclassing UITableViewController instead of UIViewController.
you need to put UIViewController as a subclass and connect IBoutlet of UITableview in XIB with its delegare. your TableVIew in UIView of XIB so you just connect fileOWner to UIView as a View and UITableview with your TableView Outlate.
#interface MySubscriptionsViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
OR
else there you remaining some referance of old copy you trying with restart xcode and remove catch or clean derive data
I just had the same issue; I fixed it by subclassing my newly created viewController file.
I was subclassing my newly created tableView file by mistake.
Or
If you want the table view to be the root view in your initial view (it will fill up the whole screen with cells) then you will delete the view in the project outline. second you will control drag the table view in the project outline to the menu (above it) and then you will click delegate for the outlet and do the same for the data source. finally you will open the table view controller file and add UITableViewDelegate and UITableViewDataSource so that it looks like this (using your created name of course).
class MainMenuTableViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource
Hope this helps.
I have developed a Tabbed Style Application in Xcode. I have run into a complication.
I am happy with my progress, But in Pic 2 or Scene 2 or SelectedCellViewController.m I don't want to see all the table cells like in Pic1 or Scene1 Below. I only want to see one table cell and the relevant table cell to link to Pic 3 or Scene 3.
You can choose a table cell in Pic 1 or Scene 1, Then you can see a pic of that color you picked and i will include some info beneath the picture. Now you can see in Pic 2 or Scene 2 there are multiple Table Cells beneath the picture. I only want to show the Relevant Table Cell so you see a larger version, I have already coded the functionality but I am confused how to get rid of the rest of the cells in Pic 2 or Scene 2.
I'm not to sure how to do this, Any help would be much Appreciated.
SelectcellViewController.h
#interface SelectedCellViewController : UIViewController {
NSString *labelText;
UIImage *banner;
IBOutlet UILabel *label;
IBOutlet UIImageView *imageView;
IBOutlet UITableView *sampleViewDecors;
UINavigationController *navigationController;
NSArray *sitesArray;
NSArray *bannerImages;
}
#property (nonatomic, copy) NSString *labelText;
#property (nonatomic, retain) UIImage *banner;
#property (nonatomic, retain) UITableView *sampleViewDecors;
#property (nonatomic, retain) NSArray *sitesArray;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) NSArray *bannerImages;
#end
viewControllerToShow.m
#import "SelectedCellViewController.h"
#import "DetailViewController.h"
#interface SelectedCellViewController ()
#end
#implementation SelectedCellViewController
#synthesize labelText;
#synthesize banner;
#synthesize sampleViewDecors;
#synthesize sitesArray;
#synthesize bannerImages;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
}
return self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[label setText:self.labelText];
[imageView setImage:self.banner];
// Load up the sitesArray with a dummy array : sites
NSArray *sites = [[NSArray alloc] initWithObjects:#"Click here for a bigger view", #"b", #"c", #"d", #"e", #"f", #"g", #"h", nil];
self.sitesArray = sites;
//[sites release];
/* Create the dummy banner images array and fill the main bannerImages array */
// Create the UIImage's from the images folder
UIImage *app = [UIImage imageNamed:#"french.png"];
UIImage *creat = [UIImage imageNamed:#"Creattica.jpg"];
UIImage *free = [UIImage imageNamed:#"Freelance.jpg"];
UIImage *net = [UIImage imageNamed:#"Netsetter.jpg"];
UIImage *rock = [UIImage imageNamed:#"Rockable.jpg"];
UIImage *tuts = [UIImage imageNamed:#"Tutsplus.jpg"];
UIImage *work = [UIImage imageNamed:#"Workawesome.jpg"];
/* Create the dummy array and fill with the UIImages. */
NSArray *banners = [[NSArray alloc] initWithObjects:app, creat, free, net, rock, tuts, work, nil];
// Set the main images array equal to the dummy array
self.bannerImages = banners;
[super viewDidLoad];
}
#pragma mark - Table View datasource methods
// Required Methods
// Return the number of rows in a section
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
return [sitesArray count];
}
// Returns cell to render for each row
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure cell
NSUInteger row = [indexPath row];
// Sets the text for the cell
cell.textLabel.text = [sitesArray objectAtIndex:row];
// Sets the imageview for the cell
//cell.imageView.image = [imagesArray objectAtIndex:row];
// Sets the accessory for the cell
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Sets the detailtext for the cell (subtitle)
//cell.detailTextLabel.text = [NSString stringWithFormat:#"This is row: %i", row + 1];
return cell;
}
// Optional
// Returns the number of section in a table view
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
#pragma mark -
#pragma mark Table View delegate methods
// Return the height for each cell
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 78;
}
// Sets the title for header in the tableview
//-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
// return #"Decors";
//}
// Sets the title for footer
//-(NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
// return #"Decors";
//}
// Sets the indentation for rows
-(NSInteger) tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
return 0;
}
// Method that gets called from the "Done" button (From the #selector in the line - [viewControllerToShow.navigationItem setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissView)] autorelease]];)
- (void)dismissView {
[self dismissViewControllerAnimated:YES completion:NULL];
}
// This method is run when the user taps the row in the tableview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailViewController *detailviewControllerToShow = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
//[viewControllerToShow setLabelText:[NSString stringWithFormat:#"You selected cell: %d - %#", indexPath.row, [sitesArray objectAtIndex:indexPath.row]]];
detailviewControllerToShow.banner = [bannerImages objectAtIndex:indexPath.row];
[detailviewControllerToShow setModalPresentationStyle:UIModalPresentationFormSheet];
[detailviewControllerToShow setModalTransitionStyle:UIModalTransitionStylePartialCurl];
[detailviewControllerToShow.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissView)]];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailviewControllerToShow];
detailviewControllerToShow = nil;
[self presentViewController:navController animated:YES completion:NULL];
navController = nil;
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Tapped row!"
// message:[NSString stringWithFormat:#"You tapped: %#", [sitesArray objectAtIndex:indexPath.row]]
// delegate:nil
// cancelButtonTitle:#"Yes, I did!"
// otherButtonTitles:nil];
// [alert show];
// [alert release];
self.labelText = nil;
self.banner = nil;
//[label release];
// [imageView release];
[super viewDidUnload];
}
- (void)viewDidUnload {
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Your tableView has as many rows as there are values in sitesArray. If there is only one value, or if you change numberOfRowsInSection, you will get a table with one row.
// Return the number of rows in a section
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
return 1;
}
I'm making my first app and I’m using XCode 4 with a Storyboard. Thanks to this place, lots of tutorials, Apple’s archives databases and a bit of me, I’m slowly getting the basics together. It’s an app populated from a plist. The plist is an array with dictionaries, the dictionarires containing stings with info about different red wines in Norway. First, the plist populates a TableView. I’m using NSSortDescritor to sort the TableView and added a button to the navigation bar for resorting if I want it displayed by another value. It looks like this:
RootTableViewController.h:
#import <UIKit/UIKit.h>
#interface RootTableViewController : UITableViewController <UIActionSheetDelegate> {
NSMutableArray *sortedObjects;
}
-(IBAction)sortButtonPressed:(id)sender;
#end
RootTableViewController.m:
#import "RootTableViewController.h"
#import "ObjectCell.h"
#import "DetailViewController.h"
#interface RootTableViewController ()
#end
#implementation RootTableViewController
- (IBAction)sortButtonPressed:(id)sender;
{
UIActionSheet *sort = [[UIActionSheet alloc]
//InitWithStyle etc for sheet
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSSortDescriptor *sortDesc;
if (buttonIndex == 0) {
sortDesc = [[NSSortDescriptor alloc] initWithKey:#"Name" ascending:YES];
[sortedWines sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
}
if (buttonIndex == 1) {
sortDesc = [[NSSortDescriptor alloc] initWithKey:#"Country" ascending:YES];
[sortedWines sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
}
[self.tableView reloadData];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *myfile = [[NSBundle mainBundle]
pathForResource:#"Objects" ofType:#"plist"];
sortedObjects = [[NSMutableArray alloc]initWithContentsOfFile:myfile];
NSSortDescriptor * sortDesc = [[NSSortDescriptor alloc] initWithKey:#"Popularity" ascending:YES];
[sortedObjects sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (void)viewWillAppear:(BOOL)animated {
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [sortedObjects count];
}
//(I’m using a Custom Cell for the TableView)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"objectCell";
ObjectCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ObjectCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.nameLabel.text = [[sortedObjects objectAtIndex:indexPath.row] valueForKey:#"Name"];
cell.countryLabel.text = [[sortedObjects objectAtIndex:indexPath.row] valueForKey:#"Country"];
return cell;
}
#pragma mark - Table view delegate
//Then the selected object is sent to the DetailViewController in this segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"DetailSegue"]) {
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *detailViewController = [segue destinationViewController];
detailViewController.selectedObject = [sortedObjects objectAtIndex:selectedRowIndex.row];
}
}
#end
Then the DetailViewController recieves the selected object to populate the Labels and ImageViews with the data from it.
DetailViewController.h:
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel *districtLabel;
#property (nonatomic, strong) IBOutlet UILabel *countryLabel;
#property (nonatomic, strong) IBOutlet UIImageView *bottleImageView;
#property (nonatomic, strong) NSString *selectedObject;
#end
DetailViewController.m:
#import "WinesDetailViewController.h"
#interface WinesDetailViewController ()
#end
#implementation WinesDetailViewController
#synthesize districtLabel,countryLabel,bottleImageView;
#synthesize selectedObject;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidAppear:(BOOL)animated
{
self.title = [selectedObject valueForKey:#"Name"];
[super viewDidAppear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
districtLabel.text = [selectedObject valueForKey:#"District"];
countryLabel.text = [selectedObject valueForKey:#"Country"];
bottleImageView.image = [UIImage imageNamed:[selectedObject valueForKey:#"Image"]];
self.navigationController.navigationBar.translucent = YES;
self.wantsFullScreenLayout = YES;
//Then I’ve added recognizers for left and right swiping:
UISwipeGestureRecognizer *leftGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeDetectedLeft:)];
leftGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:leftGesture];
UISwipeGestureRecognizer *rightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeDetectedRight:)];
rightGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:rightGesture];
}
//And the voids to handle the swipes:
- (void)swipeDetectedRight:(UISwipeGestureRecognizer *)sender
{
//Access previous cell in TableView
}
- (void)swipeDetectedLeft:(UISwipeGestureRecognizer *)sender
{
//Access next cell in TableView
}
//Some more besic code for the view..
#end
As you can see, I’ve added UISwipeGestureRecognizers in the DetailViewController, because I want to reload it with data from the previous cell to when swiped to the right, and next cell when swiped to the left. Now I have no idea how to handle the voids for swipe detected, how can I reach selectedRowIndex from DetailView and swipe through cells? I’m new to programming, have been trying to figure this out for a long time now, so code examples would be great so the answer don't lead to 100 new questions if you know what I mean. Thank you so much if you can help me.
One way to go about this is to pass the "sorted" datasource array to the DetailViewController and the indexpath through the "prepareForSegue" method.
RootTableViewController.h:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"DetailSegue"]) {
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *detailViewController = [segue destinationViewController];
detailViewController.selectedObject = [sortedObjects objectAtIndex:selectedRowIndex.row];
//added code
detailViewController.detailsDataSource = [[NSArray alloc]initWithArray:sortedObjects];
detailViewController.detailIndex = selectedRowIndex.row;
}
}
Then you could reload the UI elements of the DetailViewController.
Here is the declaration of the new properties.
DetailViewController.h:
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel *districtLabel;
#property (nonatomic, strong) IBOutlet UILabel *countryLabel;
#property (nonatomic, strong) IBOutlet UIImageView *bottleImageView;
#property (nonatomic, strong) NSString *selectedObject;
// added code
#property (strong, nonatomic) NSArray *detailsDataSource;
#property int detailIndex;
#end
Don't forget to synthesize the new properties
#synthesize detailsDataSource,detailIndex;
//And the voids to handle the swipes:
- (void)swipeDetectedRight:(UISwipeGestureRecognizer *)sender
{
//Access previous cell in TableView
if (detailIndex != 0) // This way it will not go negative
detailIndex--;
districtLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"District"]];
countryLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Country"];
bottleImageView.image = [UIImage imageNamed:[[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Image"]];
}
- (void)swipeDetectedLeft:(UISwipeGestureRecognizer *)sender
{
//Access next cell in TableView
if (detailIndex != [detailsDataSource count]) // make sure that it does not go over the number of objects in the array.
detailIndex++; // you'll need to check bounds
districtLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"District"]];
countryLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Country"];
bottleImageView.image = [UIImage imageNamed:[[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Image"]];
}
//Some more besic code for the view..
#end
Give this a try it might work for you. Otherwise, I think you might want to take a look at Scrollview and "paging." iPhone/iPad users are used to this UI design, and you might be able to modify it to fit what you are doing.
First here is the code showing the uiviewcontroller which contain the uitableview:
//View Controller with navigation bar
InAppPurchaseViewController *purchaseViewController = [[InAppPurchaseViewController alloc] init];
purchaseViewController.title = #"Liste de packs";
purchaseViewController.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissViewController:)] autorelease];
//Creation de la navigation bar et release du viewcontroller
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:purchaseViewController] autorelease];
[purchaseViewController release];
container = [[UIViewController alloc] init];
[container setView:[[CCDirector sharedDirector] openGLView]];
[container setModalTransitionStyle: UIModalTransitionStyleCoverVertical];
[container presentModalViewController: navController animated: YES];
here is my uitableviewcell:
InAppPurchaseCell.h
#interface InAppPurchaseCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIImageView *ImageThumbnail;
#property (strong, nonatomic) IBOutlet UIButton *BuyButton;
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (strong, nonatomic) IBOutlet UILabel *PriceLabel;
#end
InAppPurchaseCell.m
#implementation InAppPurchaseCell
#synthesize PriceLabel;
#synthesize TitleLabel;
#synthesize BuyButton;
#synthesize ImageThumbnail;
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
}
#end
InAppPurchaseCell.xib
All the iboutlet are linked correctly
And :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifierCasual = #"ShopCell";
InAppPurchaseCell *cell = (InAppPurchaseCell*)[tableView dequeueReusableCellWithIdentifier:cellIdentifierCasual];
if (cell == nil)
{
cell = (InAppPurchaseCell*)[[[NSBundle mainBundle] loadNibNamed:#"InAppPurchaseCell" owner:nil options:nil]lastObject];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
else
{
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
Packages *packages = [PackagesParser loadData];
Package *package = [packages.Packages objectAtIndex:indexPath.row];
cell.ImageThumbnail.image = [UIImage imageNamed:#"Icon-Small.png"];
cell.PriceLabel.text = #"0,75$";
cell.TitleLabel.text = package.Name;
return cell;
}
What's hapenning when the table pop up :
2012-07-13 13:56:55.378 Testing[1276:1c103] *** Terminating app due to uncaught
exception 'NSUnknownKeyException', reason: '[<NSObject 0xa10da00>
setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key ImageThumbnail.'
At this line :
cell = (InAppPurchaseCell*)[[[NSBundle mainBundle] loadNibNamed:#"InAppPurchaseCell" owner:nil options:nil]lastObject];
Does someone has an idea ?
this may help you
InAppPurchaseCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell=[[InAppPurchaseCell alloc]initWithFrame:CGRectMake(0, 0, 200, 100)
reuseIdentifier:#"ShopCell"];
}
When I separated a ViewController included in TableView and TableViewDataSource files,
I got a run-time error : "..EXC_BAD_ACCESS ..".
There is whole source below.
// ViewController file
<ViewController.h>
#interface ViewController : UIViewController <UITableViewDelegate>
#property (strong, nonatomic) UITableView *tableView;
#end
<ViewController.m>
- (void)viewDidLoad
{
**DS1 *ds = [[DS1 alloc] init];**
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 100, 320, 200) style:UITableViewStylePlain];
_tableView.delegate = self;
**_tableView.dataSource = ds;**
[self.view addSubview:_tableView];
}
// TableViewDataSource file
<DS1.h>
#interface DS1 : NSObject <UITableViewDataSource>
#property (strong, nonatomic) NSArray *dataList;
#end
<DS1.m>
#import "DS1.h"
#implementation DS1
#synthesize dataList = _dataList;
- (id)init
{
self = [super init];
if (self) {
_dataList = [NSArray arrayWithObjects:#"apple",#"banana", #"orange", nil];
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_dataList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [_dataList objectAtIndex:indexPath.row];
return cell;
}
#end
If I change the code of ViewController.m from
_tableView.dataSource = ds;
to
_tableView.dataSource = self;
, then it's ok. (Of course, after DataSource methods had been appended to ViewController.m)
I cannot find any problems, help me and thanks in advance.
If this is ARC you have to create an instance variable or a #property for your dataSource.
You allocate your dataSource ds as a local variable. But the dataSource property of the tableView does not retain ds. So at the end of viewDidLoad ARC will release ds and it gets deallocated.
save ds as a property of your viewController. like this:
#interface ViewController : UIViewController <UITableViewDelegate>
#property (strong, nonatomic) UITableView *tableView;
#property (strong, nonatomic) DS1 *dataSource;
#end
- (void)viewDidLoad
{
[super viewDidLoad]; // <-- !!!
self.dataSource = [[DS1 alloc] init];
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 100, 320, 200) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self.dataSource;
[self.view addSubview:_tableView];
}