How to create UITableView and detail view separately - iphone

I've created an app using single view based.Now I have to display 15 number of menus and description about each menu.So I thought of using UITableView inserting in that.While selecting a cell it should display long text & image content.Do i have to create each ViewController for each description or any shortcuts to add description programmatically
Here is my code for table view
- (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];
}
// Set up the cell...
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:15];
cell.textLabel.text = [NSString stringWithFormat:#"Cell Row #%d", [indexPath row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// open a alert with an OK and cancel button
NSString *alertString = [NSString stringWithFormat:#"Clicked on row #%d", [indexPath row]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertString message:#"" delegate:self cancelButtonTitle:#"Done" otherButtonTitles:nil];
[alert show];
[alert release];
}
This is for creating UIAlertView when cell is touched.
How can i do for long text and image display.Any ideas pls.

I think you can use a navigation controller and push tableView on it. On selection of a cell of table you should push a detailView (one detail view for all cells). This works only if you have to show same format of details data in the detailView. Else if you have to different screens for each selection, then you can design all those screens which will also make it heavy.

You can create a single ViewController wich initialize with image and text, inside view controller you should create UITextView and UIImageView. ViewController must be something like this:
#interface ViewController : UIViewController {
UIImageView *imageView;
UITextView *textView;
}
-(id)initWithText:(NSString *)text image:(UIImage *)image;
#end
#implementation ViewController
-(id)initWithText:(NSString *)text image:(UIImage *)image {
if (self = [super init]) {
//ImageView initialization
imageView.image = image;
//TextViewInitialization
textView.text = text;
}
return self;
}
#end
In view controller where table view you can create 2 arrays with corresponding images and text to cells.
Then didSelectRowAtIndexPath: must looks like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ViewController *vc = [[ViewController alloc]initWithText:[textArray objectAtIndex:indexPath.row] image:[imagesArray objectAtIndex:indexPath.row]];
[[self navigationController] pushViewController:vc animated:YES];
[vc release];
}

Related

Xcode how to link UITableView Cells to a new View Controller

I currently have developed a Tabbed Based Application. The first Tab is decors which displays Colour Swatches or Images in a TableView Structure. Currently when you push on a image or Colour swatch An alert pops up saying which table cell you have pushed. I instead want to link each table cell image or Colour swatch to a new view controller showing a bigger image of that image or colour swatch. A modal would also do fine
#import "TableViewsViewController.h"
#implementation TableViewsViewController
#pragma mark -
#pragma mark Synthesizers
#synthesize table;
#synthesize sitesArray;
#synthesize imagesArray;
#pragma mark -
#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 -
#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] autorelease];
}
// 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;
}
// This method is run when the user taps the row in the tableview
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
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];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
NSLog(#"Memory Warning!");
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
self.table = nil;
self.sitesArray = nil;
self.imagesArray = nil;
[super viewDidUnload];
}
- (void)dealloc {
[table release];
[sitesArray release];
[imagesArray release];
[super dealloc];
}
#end
Part where the Alert is
// This method is run when the user taps the row in the tableview
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
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];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
In didSelectRowAtIndexPath you can just init another view controller and present. You can present it from self.navigationController so that there is a back button if you wish. Here I show it presented modally:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Deselect row
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Declare the view controller
UIViewController *anotherVC = nil;
// Determine the row/section on the tapped cell
switch (indexPath.section) {
case 0:
switch (indexPath.row) {
case 0: {
// initialize and allocate a specific view controller for section 0 row 0
anotherVC = [[ViewControllerForRowZeroSectionZero alloc] init];
break;
}
case 1: {
// initialize and allocate a specific view controller for section 0 row 1
anotherVC = [[ViewControllerForRowOneSectionZero alloc] init];
break;
}
}
break;
case 1: {
// initialize and allocate a specific view controller for section 1 ALL rows
anotherVC = [[ViewControllerForAllRowsSectionOne alloc] init];
break;
}
}
// Get cell textLabel string to use in new view controller title
NSString *cellTitleText = [[[tableView cellForRowAtIndexPath:indexPath] textLabel] text];
// Get object at the tapped cell index from table data source array to display in title
id tappedObj = [sitesArray objectAtIndex:indexPath.row];
// Set title indicating what row/section was tapped
[anotherVC setTitle:[NSString stringWithFormat:#"You tapped section: %d - row: %d - Cell Text: %# - Sites: %#", indexPath.section, indexPath.row, cellTitleText, tappedObj]];
// present it modally (not necessary, but sometimes looks better then pushing it onto the stack - depending on your App)
[anotherVC setModalPresentationStyle:UIModalPresentationFormSheet];
// Have the transition do a horizontal flip - my personal fav
[anotherVC setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
// The method `presentModalViewController:animated:` is depreciated in iOS 6 so use `presentViewController:animated:completion:` instead.
[self.navigationController presentViewController:anotherVC animated:YES completion:NULL];
// We are done with the view controller. It is retained by self.navigationController so we can release it (if not using ARC)
[anotherVC release], anotherVC = nil;
}
You're 90% of the way there! In didSelectRowAtIndexPath, instead of putting up the alert, instantiate and set up the view controller whose view you want to show and call presentViewController:animated:.
See my book: http://www.apeth.com/iOSBook/ch19.html#_presented_view_controller
Are u using Storyboard?
If so, you can build a segue, set it to Modal or Push. Pointing from the TableView to the destination ViewController
Then name it with an identifier in the segue's inspector.
Then in didSelectRowAtIndexPath, call performSegue: withIdentifier
You can also setup the destination ViewController based on the cell selected in prepareForSegue.
Hope it helps.

how to add programmatically drop down menu in navigation bar?

can anyone tell. how to create drop down menu in iPhone,and i want add drop down menu in navigateion bar (my concept is sorting(filter) so i want three buttons in menu name,title,description .....)
You can use a UIPopoverController for iPhone.
It's available here.
In the popover you can add a UIPickerView and there's the drop-down.
Basically , on iPhone you can use a UITableView or UIPickerView to simulate a drop down.
And to place it in a nice container you can use the above mentioned popover.
There is no such a component in iOS, so you need to create it by yourself.
You can do that by adding a UIView under your button, and animate it.
Something like...
[self.view addSubview:myMenu];
[myMenu setFrame:CGRectMake(100,30,150,0)];
[UIView animateWithDuration:0.4 animation:^{
[myMenu setFrame:CGRectMake(100,30,150,200)];
}];
//on Drop down button click
-(IBAction)btnDropdownPressed:(id)sender{
if (![popoverController isPopoverVisible])
{
PopOverViewController *attShow=[[PopOverViewController alloc]initWithNibName:#"PopOverViewController" bundle:nil];
NSLog(#"arrFiles==%#",arrFiles);
attShow.arrFiles=arrFiles;
{
popoverController=[[[UIPopoverController alloc]initWithContentViewController:attShow] retain];
[popoverController setPopoverContentSize:CGSizeMake(500,250)];
[popoverController presentPopoverFromRect:CGRectMake(0,0, 500, 30) inView:btnMore permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
}else {
[popoverController dismissPopoverAnimated:YES];
}
}
PopOverViewController.h
{
IBOutlet UITableView *tblView;
NSArray *arrFiles;
}
#property(nonatomic,retain)NSArray *arrFiles;
PopOverViewController.m
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section
{
return [self.arrFiles count];
}
-(CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 40;
}
- (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];
}
cell.textLabel.text=[self.arrFiles objectAtIndex:indexPath.row];
cell.textLabel.font=[UIFont fontWithName:#"Arial" size:14.0f];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
return cell;
}

tableview is crashing on clicking on cell or on scrolling in ios 5

I made a demo empty app and add a navigation controller with the view
UINavigationController *navBar = [[UINavigationController alloc]initWithRootViewController:objFirstViewControllerViewController];
[self.window addSubview:navBar.view];
After it i add a table view on the first view controller like this .
UITableView* demotableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 400) style:UITableViewStylePlain];
demotableView.delegate = self;
demotableView.dataSource = self;
[self.view addSubview:demotableView];
and the delegate function of the table view and main cell for row function like this way
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.text = #"Hello this is sample text";
cell.textLabel.minimumFontSize = 12;
cell.textLabel.adjustsFontSizeToFitWidth = TRUE;
cell.textLabel.font = [UIFont fontWithName:#"Copperplate" size:18];
return cell;
}
But when i scroll on my table or click any cell to go on the next view it just crash and give these two error on clicking and scrolling respectively.
[__NSCFArray tableView:didSelectRowAtIndexPath:]
[__NSCFDictionary tableView:cellForRowAtIndexPath:]
I don't understand what is getting wrong this code it have been working with the prior os properly
Any body can help please ?
Here is the code for did select row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Second *anotherViewController = [[Second alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:anotherViewController animated:YES];
}
and no of row is this one
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 15;
}
Actually I misused the ARC what are the changes I made to make the app run successfully actually it was crashing due to memory leak I reference the class in delegate with local object but the it got released when it tried to add the data on it and when table's delegate and datasource try to add the things in the current class it was released and it throw message from those message instances, I was stuck because I was thinking it is happening due to me having taken an empty kind of application but after adding the lines below in the delegate class I got the problem solved.
What I did in the delegate class in the .h file:
FirstViewControllerViewController *objFirstViewControllerViewController;
#property (strong, nonatomic) FirstViewControllerViewController *objFirstViewControllerViewController;
Then my table started behaving properly and all things that I was having problem in.
Replace your code by this and try:
- (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 = #"Hello this is sample text";
cell.textLabel.minimumFontSize = 12;
cell.textLabel.adjustsFontSizeToFitWidth = TRUE;
cell.textLabel.font = [UIFont fontWithName:#"Copperplate" size:18];
return cell;
}
Hope this helps.
Please try this....
add your table view like this..
productList = [[UITableView alloc] initWithFrame:CGRectMake(0,102, 320, 267) style:UITableViewStylePlain];
productList.delegate = self;
productList.dataSource = self;
productList.backgroundColor = [UIColor clearColor];
[self.view addSubview:productList];
and add these methods....
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return (your row count);
}
// 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:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]autorelease];
}
// Configure the cell.
cell.textLabel.text = #"Title";
cell.detailTextLabel.text = formattedString;
cell.detailTextLabel.textColor = [UIColor darkGrayColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Second *anotherViewController = [[Second alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:anotherViewController animated:YES];
}
Since you have set demotableView.delegate = self;
you have to implement the tabelView: didSelectRowAtIndexPath: function which solves the crash on selecting(on Click) a Cell.
To resolve the crash of scrolling, you hav to implement
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
method.
P.S: In the cellForRowAtIndexPath:, all the lines except cell.textLabel.text should be inside
if(cell == nil){
}
and please follow proper maemory management rules

UITableView not displaying data from array

Code:
In .h:
NSMutableArray *contentArray;
I'm declaring my array.
In .m
- (void)viewDidLoad
{
[super viewDidLoad];
contentArray = [[NSMutableArray alloc] initWithObjects:#"view", #"browse", #"create", nil];
// 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;
}
I'm setting it up in my view did load.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [contentArray count];
}
I'm setting the number of rows to the array 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] autorelease];
}
// Configure the cell...
[[cell textLabel] setText:[contentArray objectAtIndex:indexPath.row]];
return cell;
}
Nothing. But if I do "[[cell textLabel] setText:#"Hello World."];" instead, it works fine.
Are you at least getting 3 empty rows in table ? If yes then just change your code
NSString *tempString = [your_array objectAtIndex:indexPath.row];
cell.textLabel.text = tempString;
If you are not even getting empty strings then make property of your array in .h file. Synthesize it in .m (also release it in delloc function) and finally in viewDidLoad right following
NSMutableArray tempContentArray = [[NSMutableArray alloc] arrayWithObjects:#"view", #"browse", #"create", nil];
self.contentArray=tempArray;
and then write following code to get cell title
NSString *tempString = [self.contentArray objectAtIndex:indexPath.row];
cell.textLabel.text = tempString;
Try to initialize your Array in your init method or call reloadDataon your UITableView after you set your Array.
Your code in .m file is fine. Write property .h file synthesize and dealloc your NSMutable array .m file it may be help you.
simply use following line of code
//initlize nsarray with objects.
-(void)viewDidLoad
{
NSArray *practice_ArrayForDisplayingEx=[NSArray alloc]initWithObjects:#"bhupi",#"bhupi",#"bhupi",#"bhupi",nil];
}
//then use in tableview.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
// UIButton *practice_takeTest_button;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]autorelease];
}
cell.textLabel.text =[practice_ArrayForDisplayingEx objectAtIndex:indexPath.row];
cell.textLabel.font=[UIFont fontWithName:#"Arial" size:15];
return cell;
}
make sure you included UITableViewDelegate & UITableViewDataSourse prtocol in .h file.
hope it will help you..
Make sure that your .h implements the tableview delegate and datasource... should look like this
#interface myClass : UITableViewController <UITableViewDelegate, UITableViewDataSource>
then make this code in your ViewDidLoad method
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];

add TableView subview crashes app

I am trying to add a tableview so when someone press a certain button, the view would switch into tableview with a few choices.
Here is my code for the button:
-(IBAction)buttonPressed:(id)sender
{
LevelChoice *level = [[LevelChoice alloc] initWithNibName:nil bundle:nil];
[self.view addSubview:level.view];
[level release];
}
Here are code snap from my subclass of UITableViewController:
LevelChoice.h
Code:
#interface LevelChoice : UITableViewController {
NSArray *choices;
}
LevelChoice.m
Code:
-(void)viewDidLoad
{
choices = [[NSArray alloc] initWithObjects:#"Level 1", #"Level 2", #"Level 3", nil];
[super viewDidLoad];
}
Code:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
-(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];
}
cell.text = [choices objectAtIndex:indexPath.row];
return cell;
}
Does anyone know what am I missing?
Distinguish between Controllers and Views. You can
either present the UITableViewController with presentModalViewController:animated: or with pushViewController:animated:. (Yes, in this case you can release it.)
or just keep a UITableView in your existing view controller and show or hide it as necessary with the hidden property. Of course you need to implement the datasource and delegate methods for the table.