I have made an a Tabbed Bar Application in Xcode and the First Tab is Decors. I asked a previous question on integrating a XIB Project into a StoryBoard Tabbed Project.
I have Been Successfully in the integration of this, And it works but when I push on one of the Deocrs, Or Table Cells I get the following Error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SelectedCellViewController" nib but the view outlet was not set.
If I put the Original Alert into my project The cell linking starts to work again.
Below are pics, links and code to my project, So you can see how it works
StoryBoard Project
XIB Project
DecorsViewController_iPhone.h
#import <UIKit/UIKit.h>
#interface DecorsViewController_iPhone : UIViewController
{
IBOutlet UITableView *tableViewDecors;
NSArray *sitesArray;
NSArray *imagesArray;
}
#property (nonatomic, retain) UITableView *tableViewDecors;
#property (nonatomic, retain) NSArray *sitesArray;
#property (nonatomic, retain) NSArray *imagesArray;
#end
DecorsViewController_iPhone.m
#import "DecorsViewController_iPhone.h"
#import "SelectedCellViewController.h"
#interface DecorsViewController_iPhone ()
#end
#implementation DecorsViewController_iPhone
#synthesize tableViewDecors;
#synthesize sitesArray;
#synthesize imagesArray;
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
// Load up the sitesArray with a dummy array : sites
NSArray *sites = [[NSArray alloc] initWithObjects:#"a", #"b", #"c", #"d", #"e", #"f", #"g", #"h", nil];
self.sitesArray = sites;
//[sites release];
UIImage *active = [UIImage imageNamed:#"a.png"];
UIImage *ae = [UIImage imageNamed:#"b.png"];
UIImage *audio = [UIImage imageNamed:#"c.png"];
UIImage *mobile = [UIImage imageNamed:#"d.png"];
UIImage *net = [UIImage imageNamed:#"e.png"];
UIImage *photo = [UIImage imageNamed:#"f.png"];
UIImage *psd = [UIImage imageNamed:#"g.png"];
UIImage *vector = [UIImage imageNamed:#"h.png"];
NSArray *images = [[NSArray alloc] initWithObjects: active, ae, audio, mobile, net, photo, psd, vector, nil];
self.imagesArray = images;
//[images release];
[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];
SelectedCellViewController *viewControllerToShow = [[SelectedCellViewController alloc] initWithNibName:#"SelectedCellViewController" bundle:[NSBundle mainBundle]];
[viewControllerToShow setLabelText:[NSString stringWithFormat:#"You selected cell: %d - %#", indexPath.row, [sitesArray objectAtIndex:indexPath.row]]];
[viewControllerToShow setImage:(UIImage *)[imagesArray objectAtIndex:indexPath.row]];
[viewControllerToShow setModalPresentationStyle:UIModalPresentationFormSheet];
[viewControllerToShow setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[viewControllerToShow.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissView)]];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewControllerToShow];
viewControllerToShow = 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];
}
#pragma mark - Memory management
- (void)didReceiveMemoryWarning {
NSLog(#"Memory Warning!");
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
self.sitesArray = nil;
self.imagesArray = nil;
[super viewDidUnload];
}
//- (void)dealloc {
//[sitesArray release];
//[imagesArray release];
// [super dealloc];
//}
#end
SelectedCellViewController.h
#interface SelectedCellViewController : UIViewController {
NSString *labelText;
UIImage *image;
IBOutlet UILabel *label;
IBOutlet UIImageView *imageView;
}
#property (nonatomic, copy) NSString *labelText;
#property (nonatomic, retain) UIImage *image;
#end
viewControllerToShow.m
#import "SelectedCellViewController.h"
#implementation SelectedCellViewController
#synthesize labelText;
#synthesize image;
- (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.image];
}
- (void)viewDidUnload {
self.labelText = nil;
self.image = nil;
//[label release];
// [imageView release];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
check the class inherited by the "The controller to be shown on click".XIB in the identity inspector .It seems you have not set the class for the "to be shown" XIB and the view outlet of the same XIB.
Related
So far I have made a UITableView in a HabitViewControlle with a button to add a new cell. When the cell is tapped, a detialViewController is revealed. In this View their is a textField, that when tapped a UIPicker is launched. I want to set the title of a tableViewCell to the picker selection.. I have made a string called cellName and I can send it to the other ViewController. I also made it so that when the picker is changed, I set the string cellName to the title I want the cell to be when the picker selection is selected. So I almost have it ready, except actually setting the cell title to the string when the cellName is set, and the picker selection has changed. If this didn't make sense, send a comment to me, and I will try to help, because I hard time writing my question into words
habitViewController.h
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#interface HabitViewController : UITableViewController <DetailViewDelegate> {
UITableViewCell *cell;
}
#end
.m
#import "HabitViewController.h"
#import "DetailViewController.h"
#interface HabitViewController () {
NSMutableArray *_objects;
}
#property(strong, nonatomic) NSString *cellName2;
#end
#implementation HabitViewController
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[self.editButtonItem setTintColor:[UIColor colorWithRed:.33 green:.33 blue:.33 alpha:1]];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
addButton.tintColor = [UIColor colorWithRed:.33 green:.33 blue:.33 alpha:1];
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"nav_bar.png"] forBarMetrics:UIBarMetricsDefault];
//if ([cellName isEqualToString:#"Hello World"]) {
// }
}
- (void)viewDidAppear:(BOOL)animated {
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender
{
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
NSDate *object = _objects[indexPath.row];
cell.textLabel.text = [object description];
cell.textLabel.text = #"New Habit";
NSLog(#"%#",self.cellName2);
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_objects removeObjectAtIndex:indexPath.row];
[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;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"showDetail"]) {
/* assigning self as delegate, telling the detail view that I implement
* setCellName2:, so it (the detailVC) can call it whenever it wants to.
*/
[segue.destinationViewController setDelegate:self];
}
}
#pragma mark - DetailViewDelegate
// note: this is just a property setter so this is not actually needed
- (void)setCellName2:(NSString *)cellName {
cellName = cellName;
NSLog(#"%#",cellName);
cell.textLabel.text = cellName;
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#protocol DetailViewDelegate <NSObject>
- (void)setCellName2:(NSString *)cellName;
#end
#interface DetailViewController : UIViewController<UIPickerViewDelegate> {
NSArray *PickerData;
}
#property (weak, nonatomic) IBOutlet UITextField *habitField;
#property (weak, nonatomic) id<DetailViewDelegate> delegate;
#property (nonatomic, strong) NSString *cellName;
#property (retain, nonatomic) NSArray *PickerData;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *doneButton;
- (IBAction)backToRoot:(id)sender;
#end
.m
#import "DetailViewController.h"
#import "HabitViewController.h"
#interface DetailViewController () {
UITableViewCell *_cell;
}
#end
#implementation DetailViewController
#synthesize PickerData;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *array = [[NSArray alloc] initWithObjects:#"Posture",#"Paludies Abbs",#"Custom", nil];
self.PickerData = array;
[self.delegate setCellName2:self.cellName];
UIToolbar *toolBar = [[UIToolbar alloc] init];
toolBar.barStyle = UIBarStyleBlackOpaque;
[toolBar sizeToFit];
[toolBar setBackgroundImage:[UIImage imageNamed:#"red_navigation_bar.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:self
action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(releasePicker)];
UIPickerView *Picker = [[UIPickerView alloc] init];
Picker.showsSelectionIndicator = YES;
Picker.delegate = self;
doneButton.image = [UIImage imageNamed:#"button.png"];
[toolBar setItems:#[flexSpace, doneButton] animated:YES];
self.habitField.inputAccessoryView = toolBar;
[self.habitField setInputView:Picker];
}
- (void)releasePicker {
[self.habitField resignFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)backToRoot:(id)sender {
[self.navigationController popToRootViewControllerAnimated:YES];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [PickerData count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [self.PickerData objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
int select = row;
if (select == 0) {
self.cellName = #"Posture";
[self.view reloadInputViews];
NSLog(#"%# Is Selected", self.cellName);
}
}
#end
I think that you want to use your delegate to set your picker in the didSelectRow method. Like this:
DetailViewController.m:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
int select = row;
if (select == 0) {
self.cellName = #"Posture";
[self.delegate setCellName2:self.cellName];
NSLog(#"%# Is Selected", self.cellName);
}
}
and back in your habitViewController:
- (void)setCellName2:(NSString *)cellName {
cellName = cellName;
NSLog(#"%#",cellName);
selectedCell.textLabel.text = cellName;
[self.tableView reloadData];
}
You also have a few problems with "cell". Assuming you have many rows, this will get re-used over and over again and will always contain the last cell it displayed, which will seldom be what you expect.
I would rename it to selectedCell and set it when the cell is touched and your other view triggered.
#interface HabitViewController : UITableViewController <DetailViewDelegate> {
UITableViewCell *savedCell;
}
I would set it here:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"showDetail"]) {
if ([sender isKindOfClass[UITableViewCell class]]) {
savedCell = (UITableViewCell *)sender;
}
/* assigning self as delegate, telling the detail view that I implement
* setCellName2:, so it (the detailVC) can call it whenever it wants to.
*/
[segue.destinationViewController setDelegate:self];
}
}
I would just use a temp cell in this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
NSDate *object = _objects[indexPath.row];
cell.textLabel.text = [object description];
cell.textLabel.text = #"New Habit";
NSLog(#"%#",self.cellName2);
return cell;
}
I fixed it with this
First in your habitViewController.h do the following :
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#interface HabitViewController : UITableViewController <DetailViewDelegate> {
UITableViewCell *cell;
}
#property (nonatomic, strong) NSString *cellNameSender;
#end
Then in your .m replace the code that looks like this with the following :
- (void)setCellName2:(NSString *)cellName {
cellName = cellName;
NSLog(#"%#",cellName);
self.cellNameSender = cellName;
}
#end
and the same with this
- (void)viewDidAppear:(BOOL)animated {
cell.textLabel.text = self.cellNameSender;
}
Now the tableViewCell should show the posture is posture is selected.
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;
}
have only been learning objective C for a couple of days now and currently baffled by tables/ UITableView etc.. I've created a table and it lists 6 names I've read up how to set the avatar (image to the left of the text) to 1 picture however I have been playing about trying to set each individual image using an array. Heres what I have, no issues just the simulator crashes constantly? Thanks in advance.
#import <UIKit/UIKit.h>
#interface SImple_TableViewController : UIViewController
<UITableViewDelegate, UITableViewDataSource>
{
NSArray * listData;
NSArray* listPics;
}
#property (nonatomic,retain) NSArray *listData;
#property (nonatomic,retain) NSArray* listPics;
#end
#import "SImple_TableViewController.h"
#implementation SImple_TableViewController
#synthesize listData, listPics;
- (void)dealloc
{
[listData release];
[listPics release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
NSArray *array = [[NSArray alloc] initWithObjects:#"Bradley", #"Glen",#"Alan",#"Sean",#"Mark",#"Luke",#"Jack", nil];
NSArray *pics = [[NSArray alloc] initWithObjects:#"ME.jpg",#"Sean.jpg",#"Glenn.jpg",#"Mark.jpg",#"Luke.jpg",#"Jack.jpg",#"Alan.jpg", nil];
self.listData = array;
// self.listPics = pics;
[array release];
[pics release];
[super viewDidLoad];
}
- (void)viewDidUnload
{
self.listData = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark -
#pragma mark Table View Data Source Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.listData count];
return [self.listPics count];
}
-(UITableViewCell*)tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{ static NSString *SimpleTableIdentifier = #"SImpleTableIdentifier";
UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier]autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
UIImage*image = [UIImage imageNamed: listPics];
cell.imageView.image = [listPics objectAtIndex:row];
return cell;
}
#end
Here's an important thing to remember: no code that occurs after return will ever be reached. FOr example:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.listData count]; // METHOD RETURNS HERE
return [self.listPics count]; // THIS LINE IS NEVER REACHED
}
You can only return once.
This same error occurs in your method -(UITableViewCell*)tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
Here's another problem that I see. This line:
NSArray *pics = [[NSArray alloc] initWithObjects:#"ME.jpg",#"Sean.jpg",#"Glenn.jpg",#"Mark.jpg",#"Luke.jpg",#"Jack.jpg",#"Alan.jpg", nil];
creates an array of NSString objects. If you wish to put UIImages into an array, then in place of #"ME.jpg", you should have [UIImage imageNamed:#"ME.jpg"]. Make sure to add the image, with the exact same name (case sensitive) to the project.
I have a simple table view which I have built using an example from a book but it doesn't work..
It is supposed to take the values from an array and display them in the cells within a table view. I have connected the table views dataSource and delegate to the file's owner and have the following code in my controller class:
Simple_TableViewController.h
#interface Simple_TableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
NSArray *listData;
}
#property (nonatomic, retain) NSArray *listData;
#end
Simple_TableViewController.m
#import "Simple_TableViewController.h"
#implementation Simple_TableViewController
#synthesize listData;
-(void)viewdidLoad{
NSArray *array = [[NSArray alloc] initWithObjects:#"Sleepy", #"Sneezy", #"Bashful", #"Happy", #"Doc", #"Grumpy", #"Dopey", #"Thorin",#"Dorin", #"Nori", #"Ori", #"Balin", #"Dwalin", #"Fili", #"Kili", #"Oin", #"Gloin", #"Bifur", #"Bofur", #"Bombur", nil];
self.listData = array;
[array release];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.listData = nil;
[super viewDidUnload];
}
- (void)dealloc {
[listData release];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.listData count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
#end
The project succeeds when compiling, but no text displays in the table cells...
UPDATE
#import <UIKit/UIKit.h>
#interface Simple_TableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *tv;
NSArray *listData;
}
#property (nonatomic, retain) NSArray* listData;
**#property (nonatomic, retain) UITableView* tv;**
#end
#import "Simple_TableViewController.h"
#implementation Simple_TableViewController
#synthesize listData, tv;
-(void)viewdidLoad{
NSArray *array = [[NSArray alloc] initWithObjects:#"Sleepy", #"Sneezy", #"Bashful", #"Happy", #"Doc", #"Grumpy", #"Dopey", #"Thorin",#"Dorin", #"Nori", #"Ori", #"Balin", #"Dwalin", #"Fili", #"Kili", #"Oin", #"Gloin", #"Bifur", #"Bofur", #"Bombur", nil];
self.listData = array;
**[tv reloadData];**
[array release];
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.listData = nil;
[super viewDidUnload];
}
- (void)dealloc {
[listData release];
[super dealloc];
}
#pragma mark -
#pragma mark Table View Data Source Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.listData count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSString *msg = #"message";
NSLog(#"%#", msg);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
#end
You're missing the numberOfSections datasource method.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
Also after changing the data in your array, you'll want to reload the table.
[yourTableViewHere reloadData];
From your last comment,you made tableview from xib file but where is IBOutlet correspond to tableview. You have to make an IBOutlet UITableView *tableview and connect it with your tableview in xib file
in my application, i'm loading images to the cells of a table. But, when i scroll the table, the image goes out of sight of the table(goes up), it wont be there even if i scroll back.
customCell.h
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell<UINavigationControllerDelegate, UIImagePickerControllerDelegate> {
UIViewController *viewController;
UIImageView *imageView;
UIButton *button;
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#property (nonatomic, assign)UIViewController *viewController;
#property (nonatomic, retain) IBOutlet UIButton *button;
-(IBAction)selectExistingPicture1;
#end
}
customCell.m
#import "CustomCell.h"
#implementation CustomCell
#synthesize imageView;
#synthesize viewController;
#synthesize button;
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated:YES];
}
- (IBAction)selectExistingPicture1 {
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsImageEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self.viewController presentModalViewController:picker animated:YES];
[picker release];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error accessing photo library" message:#"Device does not support a photo library" delegate:nil cancelButtonTitle:#"Drat!" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
UIImage *thumbnail = [image _imageScaledToSize:CGSizeMake(80, 80) interpolationQuality:1];
/*CGSize newSize = CGSizeMake(80, 80);
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();*/
imageView.image = thumbnail;
[picker dismissModalViewControllerAnimated:YES];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)dealloc {
[imageView release];
[viewController release];
[button release];
[super dealloc];
}
#end
cameraViewController.h
#import <UIKit/UIKit.h>
#interface Camera1ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> {
}
#end
cameraViewController.m
#import "Camera1ViewController.h"
#import "CustomCell.h"
#implementation Camera1ViewController
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[i
[super dealloc];
}
#pragma mark Table Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 25;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = #"CustomCellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CustomCellIdentifier] autorelease];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self
options:nil];
for (id currentObject in nib){
if ([currentObject isKindOfClass:[CustomCell class]]){
cell = (CustomCell *)currentObject;
cell.viewController = self;
break;
}
}
}
//dont know what to do here.
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
NSString *key = #"Album";
return key;
}
#end
Your problem is mostlikely due to you reusing cells and not reintializing them correctly when they come back on the screen.
OK, so when a cell goes out of view in a tableview, it is unloaded to save memory, when you choose to reuse a cell with only 1 identifier it means that everytime a cell that used that identifier comes on screen the tableview will give back a cell of that type (BUt its NOT the original cell that you configured the first time around) when it comes back a round you must assume that it is "dirty" and you must reinitialize the image and its content, if you dont youll get undesired results like you are seeing.
Another alternative (though not a good one for tableviews with lots of cells) is to give e ach cell a unique identifier, now you are guaranteed your cells wont be "dirty" because theres a one to one mapping between identifier and cells, the down side of this is that you will be using up lots of memory, which defeats the purpose of reusing cells (its as if y ou werent reusing cells at all)...
Hope this helps
from looking at your code in the previous post:
NSUInteger s= indexPath.section;
//[cell setText:[NSString stringWithFormat:#"I am cell %d", indexPath.row]];
NSUInteger r = indexPath.row;
cell.imageView.image = nil;
for (s;s==0;s++)
for(r;r==0;r++)
{
UIImage *img=imageView.image;
cell.imageView.image = img;
}
return cell;
}
i am not sure what the looping is for, but anytime a cell needs to be redrawn you are setting the cell's UIImageView to imageView.image ( I assume imageView is a property of your UIViewController) so in essence you are overwriting what is already there with that single imageView