Tabbed ios application with multiple table views - objective-c

I'm using XCode 4.2 and testing my build on iPad 5.0.
I started building an application using the standard Tabbed application in XCode and then added code to have 2 uitableviews inside the first tab.
It compiles, but the table data does not load into the view.
App delegate.h:
#interface dmbAppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UITabBarController *tabBarController;
#end
AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[[dmbFirstViewController alloc] initWithNibName:#"dmbFirstViewController" bundle:nil] autorelease];
UIViewController *viewController2 = [[[dmbSecondViewController alloc] initWithNibName:#"dmbSecondViewController" bundle:nil] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
NSLog(#"Loading first tab view from app delegate...");
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
FirstViewController.h:
#interface dmbFirstViewController : UIViewController {
ReservationsTable *reservationsController;
WaitlistTable *waitlistController;
IBOutlet UITableView *reserveTable;
IBOutlet UITableView *waitlistTable;
}
FirstViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(#"FirstView Controller - View Loading Started");
[reserveTable setDataSource:reservationsController];
[waitlistTable setDataSource:waitlistController];
NSLog(#"FirstView Controller - Loading Table Views..");
[reserveTable setDelegate:reservationsController];
[waitlistTable setDelegate:waitlistController];
reservationsController.view = reservationsController.tableView;
waitlistController.view = waitlistController.tableView;
NSLog(#"FirstView Controller - View Loading Finished");
}
Both the tables have a .h and .m with the standard table methods implemented. I also added 2 tables in the first view nib file and linked them to the file owner.
Update:
ReserveTable.h:
#interface WaitlistTable : UITableViewController <UITableViewDataSource, UITableViewDelegate>{
NSMutableArray *waitlistitems;
}
ReserveTable.m:
- (void)viewDidLoad
{
NSLog(#"View Did Load - Wait List Table");
waitlistitems = [[NSMutableArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5",#"6",#"6",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",nil] retain];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
NSLog(#"Inside number of section for Wait List table...");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"Inside numberofRows for Wait List table...");
// Return the number of rows in the section.
return [waitlistitems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Inside cell for row at index path for Wait List table...");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"1.%#" ,[waitlistitems objectAtIndex:indexPath.row]];
return cell;
}
Thoughts?

Change your viewDidLoad to this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
reservationsController = [[ReservationsTable alloc] init];
waitlistController = [[WaitlistTable alloc] init];
NSLog(#"FirstView Controller - View Loading Started");
[reserveTable setDataSource:reservationsController];
[waitlistTable setDataSource:waitlistController];
NSLog(#"FirstView Controller - Loading Table Views..");
[reserveTable setDelegate:reservationsController];
[waitlistTable setDelegate:waitlistController];
NSLog(#"FirstView Controller - View Loading Finished");
}
basically, you are never initializing your tableViewControllers (I guess that is the name of both of them, I would change their names to something like "WaitlistTableViewController" and "ReservationsTableViewController", but that is just me.) Also, setting the 'tableView' to the 'view' is unnecessary.
Or even better, initialize them in the init method for your dmbFirstViewController.
Or just use dmbFirstViewController like this:
dmbFirstViewController.h:
#interface dmbFirstViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
ReservationsTable *reservationsController;
WaitlistTable *waitlistController;
IBOutlet UITableView *reserveTable;
IBOutlet UITableView *waitlistTable;
NSMutableArray *waitlistitems;
NSMutableArray *reserveitems;
}
dmbFirstViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
waitlistitems = [[NSMutableArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5",#"6",#"6",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",nil] retain];
NSLog(#"FirstView Controller - View Loading Started");
[reserveTable setDataSource:self];
[waitlistTable setDataSource:self];
NSLog(#"FirstView Controller - Loading Table Views..");
[reserveTable setDelegate:self];
[waitlistTable setDelegate:self];
NSLog(#"FirstView Controller - View Loading Finished");
}
- (void)viewDidAppear:(BOOL)animated
{
[reserveTable reloadData];
[waitlistTable reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
NSLog(#"Inside number of section for Wait List table...");
if(tableView == waitlistTable)
{
//Return sections for waitlistTable
return 1;
}else{
//Return sections for reservedTable
return 1;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView==waitlistTable)
{
NSLog(#"Inside numberofRows for Wait List table...");
// Return the number of rows in waitlistTable section.
return [waitlistitems count];
}else{
// Return the number of rows in reservedTable section.
return [reserveditems count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == waitlistTable)
{
NSLog(#"Inside cell for row at index path for Wait List table...");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"1.%#" ,[waitlistitems objectAtIndex:indexPath.row]];
return cell;
} else {
//Create cell for reservedTable Cell
.....
return cell;
}
}
You'll have to finish off the part about reservedTable cells, I didn't have that code. Plus, I guessed on the items array for reservedTable and did not initialize it.

I think in your firstViewController you should push the views.
Assuming that reserveTable is your main table, push it like so
[self.view addSubView:reserveTable];
Also, did you import the ReserveTable.h to your firstViewController?
If yes, you should initialize the table there though.
But what i suggest, though, is to transform the firstViewController in a tableViewController, editing the App Delegate and the firstViewController.h and m, and from there initialize the table (even adding the other one too). So that would be easier!

Related

Trying to call a second table view with the items of de selected playlist in the first view

Maybe there's someone outthere who can help me fiure out my problem. I cant seem to display the playlistItems using cocoalibspotify. I have set up my playlistview and the first ableviewcontroller shows the playlist but when i try to call the items of the selected playlist I seem to get 0 numbersof row as my outputs show. the first view show how i pass the indexpath to the secondviewcontroller. the second script show my .h and .m files of the playlistitemsTavle view controller.
Overview.m - tableView with Playlists
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[playlistView deselectRowAtIndexPath:indexPath animated:NO];
playlistItemViewController *trailsController = [[playlistItemViewController alloc] initWithStyle:UITableViewStylePlain];
trailsController.currentPlaylist = [playlistArray objectAtIndex:indexPath.row];
//[[self navigationController] pushViewController:trailsController animated:YES];
[self getSongs];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showPlaylistItem"]) {
UITableViewCell *BasicCell = (UITableViewCell *) sender;
NSIndexPath *ip = [self.tableView indexPathForCell:BasicCell];
SPPlaylist *selectedPlaylist = [playlistArray objectAtIndex:ip.row];
playlistItemViewController *pivc = (playlistItemViewController *) segue.destinationViewController;
pivc.currentPlaylist = selectedPlaylist;
}
}
playlistitemsViewController.h -
#import <UIKit/UIKit.h>
#import "CocoaLibSpotify.h"
#import "Simple_PlayerAppDelegate.h"
#import "overViewController.h"
#interface playlistItemViewController : UITableViewController
{
UITableView *tableView;
}
#property (retain, nonatomic) IBOutlet UITableView *tableView;
#property (strong, readwrite, nonatomic) SPPlaylist *currentPlaylist;
#end
playlistViewController.m - this should call the playlist items
#import "playlistItemViewController.h"
#interface playlistItemViewController ()
#end
#implementation playlistItemViewController {
}
#synthesize currentPlaylist;
#synthesize tableView;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"numberOfRowsInSection: %d",[[currentPlaylist items] count]);
return [[currentPlaylist items] count];
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SubtitleCell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [[[currentPlaylist items] objectAtIndex:indexPath.row] valueForKey:#"name"];
return cell;
if (indexPath.row == 0) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SubtitleCell"];
[[cell.backgroundView superview] bringSubviewToFront:cell.backgroundView];
cell.textLabel.text = #"";
}
else{
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"SubtitleCell"];
}
SPPlaylistItem * item = [[currentPlaylist items] objectAtIndex:[[currentPlaylist items]count] - indexPath.row];
cell.textLabel.text = [item.item name];
if (item.itemClass == [SPTrack class]) {
SPTrack * track = item.item;
cell.detailTextLabel.text = [track consolidatedArtists];
}
}
return cell;
}
#end
You need to wait for the playlist to load before the items are available.
Your playlist view controller needs to use SPAsyncLoading to load the playlist, something list this:
[SPAsyncLoading waitUntilLoaded:self.currentPlaylist timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedItems, NSArray *notloadedItems) {
[self.tableView reloadData];
}];
Playlist loading can take a while, so make sure you put up some "loading" UI. You'll also need to load the visible tracks in a similar manner before their names will be available.

How to link delegate and sourcedata to only one tableview in a set of tableviews created in the mainstoryboard

Please bear with me as I am completely new at objective-c. Thanks in advance for any help you can provide!
So here is basically what I am trying to accomplish: I have 3 main tables whose contents will never change, that I therefore chose to construct in the mainstoryboard. Think of these are different grouping drilled down step by step into more and more details. So you have:
Table 1 (higher level to table 2) > Table 2 (higher level to table 3) > Table 3
Now I need to add a 4th table, but whose contents will be changed, based on a CSV file. For now I am ignoring how use CSV files and there seems to be quite a bit of info on this already. So I am electing to use Arrays using (NSArray) to store and retrive the information.
I first build the prototype of this table in the mainstoryboard so that I have an idea of what it will look like. Then I wrote the code below which ideally will update the information in table 4:
VIEWCONTROLLER.H file
#import <UIKit/UIKit.h>
#interface ViewController : UITableViewController
<UITableViewDataSource, UITableViewDelegate>
#end
VIEWCONTROLLER.M file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
NSArray *nominalManagers;
NSArray *tipsManagers;
NSArray *tipsAmt;
NSArray *nominalAmt;
- (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;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
tipsManagers = [[NSArray alloc]
initWithObjects:
#"SSG",
nil];
tipsAmt = [[NSArray alloc]
initWithObjects:
#"$tip",
nil];
nominalManagers = [[NSArray alloc]
initWithObjects:
#"Wel",
#"Gold",
#"Colch",
#"Stand",
nil];
nominalAmt = [[NSArray alloc]
initWithObjects:
#"$Wel",
#"$Gold",
#"$Colch",
#"$Stand",
nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
NSUInteger rowNum;
if (section == 0) {
rowNum = 1;
}
else if (section == 1) {
rowNum = 4;
}
else {
rowNum = 0;
}
return rowNum;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSUInteger row = [indexPath row];
NSInteger section = [indexPath section];
switch (section) {
case 0: // First cell in section 1
cell.textLabel.text = [tipsManagers objectAtIndex:[indexPath row]];
cell.detailTextLabel.text = [tipsAmt objectAtIndex:[indexPath row]];
break;
case 1: // Second cell in section 1
cell.textLabel.text = [nominalManagers objectAtIndex:[indexPath row]];
cell.detailTextLabel.text = [nominalAmt objectAtIndex:[indexPath row]];
break;
default:
cell.textLabel.text = #"WRONG SECTION";
break;
}
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 - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
My main issue is that I am unable to connect the delegate and sourcedata of this class to Table 4 (the table whose information will change). Can you help? Do you have any suggestions to better accomplish my goal?
What I understand from your question is you do not have a uitableview to connect your data source and delegate !?
I am not sure if you have added 4th viewcontroller to your storyboard yet, If not just add a UItableviewcontroller to your storyboard, create a push segue then in identity inspector choose your VIEWCONTROLLER as class name.
Add IBOutlet UITableViewto your .h file like below and in your interface builder connect your datasource and delegate. When you need refresh your tableview call [self.tableviewname reloadData];
You can use NSMutableArray to edit the items in your array, if you use NSArray array items will be static.
VIEWCONTROLLER.H file
#import <UIKit/UIKit.h>
#interface ViewController : UITableViewController
<UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, weak) IBOutlet UITableView *fourthTable;
#end
VIEWCONTROLLER.M file
#implementation ViewController
#synthesize fourthTable;
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
tipsManagers = [[NSArray alloc]
initWithObjects:
#"SSG",
nil];
tipsAmt = [[NSArray alloc]
initWithObjects:
#"$tip",
nil];
nominalManagers = [[NSArray alloc]
initWithObjects:
#"Wel",
#"Gold",
#"Colch",
#"Stand",
nil];
nominalAmt = [[NSArray alloc]
initWithObjects:
#"$Wel",
#"$Gold",
#"$Colch",
#"$Stand",
nil];
[self.fourthTable reloadData];
}

What are some reasons why custom UITableViewCells might work in iOS 6 but not iOS 5?

I am having a ton of trouble trying to get a table view to work on my iPhone. The weird thing is that it seems to work completely fine on my iOS simulator (i.e., I can add an entry to an array, and that entry shows up in my table view). However, when I try to add an entry when using my iOS device, the codes breaks on the line dequeueReusableCellWithIdentifier:. I've checked for capitalization inconsistencies, name inconsistencies, have reimplemented prepareForReuse in the custom UITableViewCell subclass, have tried defining fields in my UITableViewCell subclass using IBOutlets v. tags, and perhaps a few more things but none have worked.
This questions is tangentially related to my previous question: Debugging strategies when UITableView's cells don't load?
The tough part about programming is always knowing which question to ask, so I apologize if it turns out I am asking the wrong questions.
UPDATE 6: Problem Is Custom Layout For UITableViewCell On iOS 5
I tested using a subclass of UITableViewCell and UITableViewCell with a custom layout. Using a subclass of UITableViewCell with style UITableViewCellStyleDefault does work on both iOS 5 and iOS 6 iPhone simulator. However, using a generic UITableViewCell with a custom style crashes on iOS 5 but not iOS 6. Interestingly, I don't see a declaration for a custom UITableViewCellStyle in the documentation for UITableViewCell...
UPDATE 5: iOS 5 v. 6 + Custom UITableViewCell Subclass?
Hello: Continued testing today and it appears that it is an issue between how iOS 5 and 6 treat custom UITableViewCell subclasses. No solution yet :(
UPDATE 4: iOS 5 v. iOS 6?
So all I've been able to notice is that this seems to be an issue with iOS 5 versus iOS 6. When testing on iOS 6 using line GlassboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier] the code below works. However, neither that line nor GlassboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath] work in iOS 5. Any ideas? I somehow got it to work exactly once by changing the identifier to protocell.
UPDATE 3: I now use GitHub!
Here is the relevant repo: https://github.com/kenmhaggerty/Glassbox
UPDATE 2: More Observations
So I had added in #synthesize tableView = _tableView because I read in a response somewhere that it might help, but I now realize that it stopped my data from loading in my table view even when running on the iOS simulator. Commenting out that line of code returns the code back to how I describe it above: it works just fine on the iOS simulator but breaks on line dequeueReusableCellWithIdentifier: with no specified error, just Thread 1: breakpoint 1.1.
UPDATE 1: Relevant Code
GlassboxTableViewController.h
//
// GlassboxTableViewController.h
// Glassbox
//
// Created by Ken M. Haggerty on 10/22/12.
// Copyright (c) 2012 Ken M. Haggerty. All rights reserved.
//
#pragma mark - // NOTES (Public) //
#pragma mark - // IMPORTS (Public) //
#import <UIKit/UIKit.h>
#pragma mark - // PROTOCOLS //
//#protocol GlassboxTableViewDatasource <NSObject>
//#property (nonatomic, weak) NSMutableArray *arrayOfPlayers;
//#end
#pragma mark - // DEFINITIONS (Public) //
#interface GlassboxTableViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *arrayOfPlayers;
- (IBAction)addPlayer:(UIBarButtonItem *)sender;
//#property (nonatomic, strong) id <GlassboxTableViewDatasource> datasource;
#end
GlassboxTableViewController.m
//
// GlassboxTableViewController.m
// Glassbox
//
// Created by Ken M. Haggerty on 10/22/12.
// Copyright (c) 2012 Ken M. Haggerty. All rights reserved.
//
#pragma mark - // NOTES (Private) //
#pragma mark - // IMPORTS (Private) //
#import "GlassboxTableViewController.h"
#import "GlassboxCell.h"
#import "Player.h"
#import <MobileCoreServices/MobileCoreServices.h>
#pragma mark - // DEFINITIONS (Private) //
#define SIDEBAR_WIDTH_PERCENT 0.75
#interface GlassboxTableViewController () <UITableViewDataSource, UITableViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
//#property (nonatomic, weak) IBOutlet UITableView *tableView;
- (void)setup;
#end
#implementation GlassboxTableViewController
#pragma mark - // SETTERS AND GETTERS //
#synthesize arrayOfPlayers = _arrayOfPlayers;
#synthesize tableView = _tableView;
//#synthesize datasource = _datasource;
- (void)setArrayOfPlayers:(NSMutableArray *)arrayOfPlayers
{
_arrayOfPlayers = arrayOfPlayers;
}
- (NSMutableArray *)arrayOfPlayers
{
if (!_arrayOfPlayers) _arrayOfPlayers = [[NSMutableArray alloc] init];
// [_arrayOfPlayers addObject:[[Player alloc] initWithUsername:#"Ken H.:"]];
return _arrayOfPlayers;
}
#pragma mark - // INITS AND LOADS //
- (void)setup
{
self.tableView.dataSource = self;
self.tableView.delegate = self;
}
- (id)initWithStyle:(UITableViewStyle)style
{
NSLog(#"[initWithStyle]");
self = [super initWithStyle:style];
if (self) {
[self setup];
}
return self;
}
- (void)viewDidLoad
{
NSLog(#"[viewDidLoad]");
[super viewDidLoad];
[self setup];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
//- (void)viewDidAppear:(BOOL)animated
//{
// [super viewDidAppear:animated];
// [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width*SIDEBAR_WIDTH_PERCENT, self.view.frame.size.height)];
//}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - // PUBLIC FUNCTIONS //
- (IBAction)addPlayer:(UIBarButtonItem *)sender
{
[self alertAddPlayer];
}
#pragma mark - // PRIVATE FUNCTIONS //
- (void)alertAddPlayer
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Add New Player" message:#"Please type player name:" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
alert.tag = 1;
[alert show];
}
- (void)alertInvalidPlayer
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Invalid Name" message:#"Please type another name:" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"OK",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
alert.tag = 1;
[alert show];
}
- (void)alertAddPhoto
{
NSLog(#"[TEST] alertAddPhoto");
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
if ([mediaTypes containsObject:(NSString *)kUTTypeImage])
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.allowsEditing = YES;
// imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
// imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
imagePickerController.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
// [self presentViewController:imagePickerController animated:YES completion:nil];
imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
[self presentModalViewController:imagePickerController animated:YES];
return;
}
}
NSLog(#"[TEST] No camera available");
[self.tableView reloadData];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
if (!image) image = [info objectForKey:UIImagePickerControllerOriginalImage];
if (image)
{
[[self.arrayOfPlayers lastObject] setPhoto:[[UIImageView alloc] initWithImage:image]];
}
[self dismissImagePicker];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissImagePicker];
}
- (void)dismissImagePicker
{
// [self dismissViewControllerAnimated:YES completion:^{
// [self.tableView reloadData];
// }];
[self dismissModalViewControllerAnimated:YES];
[self.tableView reloadData];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) NSLog(#"Cancel tapped");
else
{
if (alertView.tag == 1)
{
if (buttonIndex == 1)
{
if ([[[alertView textFieldAtIndex:0] text] length] != 0)
{
[self.arrayOfPlayers addObject:[[Player alloc] initWithUsername:[[alertView textFieldAtIndex:0] text]]];
[self alertAddPhoto];
}
else [self alertInvalidPlayer];
}
}
}
}
#pragma mark - // PRIVATE FUNCTIONS (Miscellaneous) //
// TableView data source //
//- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
//{
//#warning Potentially incomplete method implementation.
// // Return the number of sections.
// return 0;
//}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return self.datasource.arrayOfPlayers.count;
return self.arrayOfPlayers.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"New Cell";
// GlassboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
GlassboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.name.text = [[self.arrayOfPlayers objectAtIndex:indexPath.row] username];
cell.action.text = #"LOADED SUCCESSFULLY";
cell.time.text = #"Just now";
cell.photo = [[self.arrayOfPlayers objectAtIndex:indexPath.row] photo];
// [((UILabel *)[cell viewWithTag:1]) setText:[[self.arrayOfPlayers objectAtIndex:indexPath.row] username]];
// [((UILabel *)[cell viewWithTag:2]) setText:#"has been added."];
// [((UILabel *)[cell viewWithTag:3]) setText:#"Just now"];
// [((UIImageView *)[cell viewWithTag:4]) setImage:[[[self.arrayOfPlayers objectAtIndex:indexPath.row] photo] image]];
[cell.contentView setFrame:CGRectMake(cell.contentView.frame.origin.x, cell.contentView.frame.origin.y, cell.contentView.frame.size.width, 120)];
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;
}
*/
// TableView delegate //
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
Let me know if I should post more.
(Your github project does not compile (Player.h/Player.m missing), so it is difficult to reproduce the issue.)
But I noticed that "Use Autolayout" is on in the MainStoryboard file. Autolayout works only on iOS 6 and later, not on iOS 5!
Please post your code. I can advice you to leave the xib files for uitableviewcell and try again. Do you use one kind of cell? or you use few different style?
===== ANSWER =====
When you create cell GlassboxCell *cell and use dequeueReusableCellWIthIdentifier you need check if cell is allocated.
// use dequeueReusableCellWithIdentifier for init cell
if (cell == nil){
cell = [[[GlassboxCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:yourIdentifier]] autorelease];
}
//rest your code for init properties for cell
ok man try to use this function instead of yours.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NewCell";
GlassboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[GlassboxCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.name.text = [[self.arrayOfPlayers objectAtIndex:indexPath.row] username];
cell.action.text = #"LOADED SUCCESSFULLY";
cell.time.text = #"Just now";
cell.photo = [[self.arrayOfPlayers objectAtIndex:indexPath.row] photo];
[cell.contentView setFrame:CGRectMake(cell.contentView.frame.origin.x, cell.contentView.frame.origin.y, cell.contentView.frame.size.width, 120)];
return cell;
}
I think I found the problem...at least it works on my project.
When you make a UITableViewController class with an older version of Xcode (say 4), the generated code for cellForRowAtIndexPath is this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
But when you make a UITableViewController with Xcode 4.5.2 (mine), the generated code for cellForRowAtIndexPath is this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
So in my case all I did was remove the "forIndexPath:indexPath" portion and it works!
(This is my first answer ever so please be gentle if I screwed up something)

My second level detail controller is not showing the initWithObjects in my array in the viewDidLoad method

I am creating a Two Level table view. And the second view is supposed to have the list of the movies I have listed below in my viewDidLoad method, but it is not showing.(You can see my screen shots attached)Does anyone know which file where I can look to see why it is not showing? The code below is from my DisclosureButtonController.m file which is to display this information after I hit the Disclosure Buttons instance on the First Level screen.
Regards,
#import "LWWDisclosureButtonController.h"
#import "LWWAppDelegate.h"
#import "LWWDisclosureDetailController.h"
#interface LWWDisclosureButtonController ()
#property (strong, nonatomic) LWWDisclosureDetailController *childController;
#end
#implementation LWWDisclosureButtonController
#synthesize list;
#synthesize childController;
//- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
//{
// self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
//if (self) {
// Custom initialization
//}
//return self;
//}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *array = [[NSArray alloc] initWithObjects:#"Toy Story", #"A Bug's Life", #"Toy Story 2", #"Monsters, Inc.", #"Finding Nemo", #"The Incredibles", #"Cars", #"Ratatouille", #"WALL-E", #"Up", #"Toy Story 3", #"Cars 2", #"Brave", nil];
self.list = array;
// Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.list = nil;
self.childController = nil;
// Release any retained subviews of the main view.
}
#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];//
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString * DisclosureButtonCellIdentifier = #"DisclosureButtonCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DisclosureButtonCellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:DisclosureButtonCellIdentifier];
}
NSUInteger row = [indexPath row];
NSString *rowString = [list objectAtIndex:row];
cell.textLabel.text = rowString;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hey, boss do you see the disclosure button?" message:#"If you're trying to drill down, touch that instead mate!" delegate:nil cancelButtonTitle:#"Won't happen again" otherButtonTitles:nil];
[alert show];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath: (NSIndexPath *)indexPath
{
if (childController == nil)
{
childController = [[LWWDisclosureDetailController alloc]initWithNibName:#"LWWDisclosureDetail" bundle:nil];
}
childController.title = #"Disclosure Button Pressed";
NSUInteger row = [indexPath row];
NSString *selectedMovie = [list objectAtIndex:row];
NSString *detailMessage = [[NSString alloc]initWithFormat:#"You pressed the disclosure button for %#.", selectedMovie];
childController.message = detailMessage;
childController.title = selectedMovie;
[self.navigationController pushViewController:childController animated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Why not start the array with the VC instead of after the VC loads? Try overriding the init method.
- (id) init {
if((self == [super init])) {
//load your array here and set
}
return self;
}
That way, on older devices, you don't have to wait after the view loads to see the array. But, however, this is my preference. I love to override init methods and create my own.
Also, for some weird reason on my SDK, I have to use NSMutableArray instead of NSArray or it won't work. Maybe you have the same issue?
Also, I've noticed NSString *selectedMovie. Instead of using just "row", use the getter indexPath.row.
Hope these suggestions helped!
Call:
[self.tableView reloadData]; (put in place of self.tableView the var or property connected to the tableView)
after the:
self.list = array;
code line in the viewDidLoad method
and put a
NSLog(#"number of rows: %d", [self.list count]);
in
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [list count];//
}
to check if it is not zero.

TableView is delegated, populates but wont group

I am having a weird problem and i couldn`t find a solution (or something similar).
The thing is, my UITableView Populates with initial info (for testing), but no matter what i do i can't seem to put it to grouped style (i can select it on the UI but it wont show)
I initially started a TabBar project and added a third navigationController view in the tabs.
#import <UIKit/UIKit.h>
#interface RootViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
NSMutableArray *tableData;
}
#property (nonatomic, retain) NSMutableArray *tableData;
-(void)initTableData;
#end
This is the header, and as you can see it has nothing out of the ordinary. The following code is inside the .m file of the header i just posted(ill only be posting uncommented code:
#synthesize tableData;
-(void)initTableData
{
tableData = [[NSMutableArray alloc] init];
[tableData addObject:#"Cidade"];
[tableData addObject:#"Veículo"];
[tableData addObject:#"Ano"];
[tableData addObject:#"Valor"];
[tableData addObject:#"Cor"];
[tableData addObject:#"Combustível"];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Busca";
UIBarButtonItem *_backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleDone target:nil action:nil];
self.navigationItem.backBarButtonItem = _backButton;
[self initTableData];
}
- (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 6;
}
// Customize the appearance of table view cells.
- (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] autorelease];
}
// Configure the cell...
cell.textLabel.text = [tableData objectAtIndex:[indexPath row]];
return cell;
}
- (void)dealloc {
[tableData release];
[super dealloc];
}
Nothing out of the ordinary again as you can see...
Any idea of what may be causing this? I tried
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
// Custom initialization.
}
return self;
}
because i don't know what else to do. (also didn't worked)
Again, i got the delegate and datasource set to File`s Owner.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Set the tab bar controller as the window's root view controller and display.
self.window.rootViewController = self.tabBarController;
RootViewController *rvc = [[RootViewController alloc] initWithStyle: UITableViewStyleGrouped];
[self.window makeKeyAndVisible];
return YES;
}
As you have modified the - (id)initWithStyle:(UITableViewStyle)style initializer to return a UITableView with a grouped style, do you call this initializer when you initialize the RootViewController?
RootViewController *rvc = [[RootViewController] alloc] initWithStyle: UITableViewStyleGrouped];
Grouped tables respond to the sections. You only have 1 section listed so you will only see the 1 group. Try and add a 2nd tableData for the 2nd group and return 2 sections. You will also have to split the data in your -cellForRowAtIndexPath by section as well to make sure the data goes to the right section.
if (indexpath.section == 0) {
// first section and first tableData
}
if (indexpath.section == 1) {
// second section and second tableData
}