sending data from DetailViewController to MasterViewController - iphone

This is what exactly I'm trying to do.
wizardviewcontroller.m
- (IBAction)onCountryClick:(id)sender {
MJDetailViewController *detailViewController = [[MJDetailViewController alloc] initWithNibName:#"MJDetailViewController" bundle:nil];
[self presentPopupViewController:detailViewController animationType:MJPopupViewAnimationSlideLeftRight];
}
User click country button a popup shows with list.
when user select a row button title should change.
This is my detailview,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
WizardViewController *mj = [[WizardViewController alloc] initWithNibName:#"WizardViewController" bundle:nil];
mj.countryselected = [countryNames objectAtIndex:indexPath.row];
[mj.countryButton setTitle:mj.countryselected forState:UIControlStateNormal];
[self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationFade];
}
DetailViewController is dismissing, but countryButtonTitle is not updating. I know this is because the wizardview is not refreshing. I would like to know the correct workaround in this case.
Hope this helps to get better answer.

Make Protocol in MJDetailViewController
#protocol MJDetailViewControllerDelegate;
#interface MJDetailViewController : UIViewController
#property (nonatomic,assign) id< MJDetailViewControllerDelegate> delegate;
#end
#protocol MJDetailViewControllerDelegate <NSObject>
- (void)selectedContry:(NSString *)title;
#end
And call like
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
NSString *title = [countryNames objectAtIndex:indexPath.row];
if ([self.delegate respondsToSelector:#selector(selectedContry:)]) {
[self.delegate selectedContry:title];
}
[self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationFade];
}
Add MJDetailViewControllerDelegate as a protocol in WizardViewController.h)
Now implement selectedContry: method in WizardViewController.m like:
- (void)selectedContry:(NSString *)title
{
[self.countryButton setTitle:title forState:UIControlStateNormal];
}
Hope it helps you.

Related

Master Detail Application - Static Table in Detail View

I'm trying to code an app in Xcode 4, with storyboarding. It's a master detail application, and it all worked fine, with the table and the detail view. But in my detail view, I would like to have a static table to display the data. In a grouped table style way, with the "key" on the left and "value" on the right, if that's a way to put it... So, it's all working fine until I put a table into my UIView. Apparently you have to put it in a UITableView for it to work, so I deleted the UIView that Xcode made for me and put in a UITableView in its place. I set it up EXACTLY the same (I think) with the identifier, title etc... and then connect the table cells up with outlets and what not. But now when I enter the view, I just get an empty table (well, not empty, just all the rows say "Detail" in rather than the actual data I want). I don't see why! D: I even changed DetailViewController.h to say "UITableViewController" as well! No avail... :( Could someone please enlighten me as to what I'm doing wrong! I bet it's really simple... :L Here's my code
MasterViewController.h
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface MasterViewController : UITableViewController
#property (strong, nonatomic) DetailViewController *detailViewController;
#property (strong) NSMutableArray *verbs;
#end
MasterViewController.m
#import "MasterViewController.h"
#import "DetailViewController.h"
#import "VerbData.h"
#interface MasterViewController () {
NSMutableArray *_objects;
}
#end
#implementation MasterViewController
#synthesize verbs = _verbs;
- (void)awakeFromNib
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
}
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.detailViewController = (DetailViewController *) [[self.splitViewController.viewControllers lastObject] topViewController];
self.title = #"Verbs";
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (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 _verbs.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"VerbCell"];
VerbData *verb = [self.verbs objectAtIndex:indexPath.row];
cell.textLabel.text = verb.infinitive;
cell.detailTextLabel.text = verb.english;
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)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
VerbData *object = [self.verbs objectAtIndex:indexPath.row];
self.detailViewController.detailItem = object;
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
VerbData *object = [self.verbs objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#import "VerbData.h"
#interface DetailViewController : UITableViewController <UISplitViewControllerDelegate>
#property (strong, nonatomic) VerbData *detailItem;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (weak, nonatomic) IBOutlet UILabel *jeOutlet;
#property (weak, nonatomic) IBOutlet UILabel *tuOutlet;
#property (weak, nonatomic) IBOutlet UILabel *ilOutlet;
#property (weak, nonatomic) IBOutlet UILabel *nousOutlet;
#property (weak, nonatomic) IBOutlet UILabel *vousOutlet;
#property (weak, nonatomic) IBOutlet UILabel *ilsOutlet;
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)configureView;
#end
#implementation DetailViewController
#pragma mark - Managing the detail item
#synthesize detailItem = _detailItem;
#synthesize jeOutlet = _jeOutlet;
#synthesize tuOutlet = _tuOutlet;
#synthesize ilOutlet = _ilOutlet;
#synthesize nousOutlet = _nousOutlet;
#synthesize vousOutlet = _vousOutlet;
#synthesize ilsOutlet = _ilsOutlet;
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
if (self.masterPopoverController != nil) {
[self.masterPopoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = self.detailItem.english;
self.jeOutlet.text = self.detailItem.je;
self.tuOutlet.text = self.detailItem.tu;
self.ilOutlet.text = self.detailItem.il;
self.nousOutlet.text = self.detailItem.nous;
self.vousOutlet.text = self.detailItem.vous;
self.ilsOutlet.text = self.detailItem.ils;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.title = self.detailItem.infinitive;
[self configureView];
}
- (void)viewDidUnload
{
[self setJeOutlet:nil];
[self setTuOutlet:nil];
[self setIlOutlet:nil];
[self setNousOutlet:nil];
[self setVousOutlet:nil];
[self setIlsOutlet:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#pragma mark - Split view
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
barButtonItem.title = NSLocalizedString(#"Master", #"Master");
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
self.masterPopoverController = popoverController;
}
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
// Called when the view is shown again in the split view, invalidating the button and popover controller.
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
self.masterPopoverController = nil;
}
#end
First thing I will try to debug is -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method. Is it return values? Try to put NSLog in this method and check it.
Or maybe this will help you:
Note: If you want to change the background color of a cell (by setting the background color of a cell via the backgroundColor property declared by UIView) you must do it in the tableView:willDisplayCell:forRowAtIndexPath: method of the delegate and not in tableView:cellForRowAtIndexPath: of the data source. Changes to the background colors of cells in a group-style table view has an effect in iOS 3.0 that is different than previous versions of the operating system. It now affects the area inside the rounded rectangle instead of the area outside of it.
The code must handle the case where dequeueReusableCellWithIdentifier answers nil...
static NSString *CellIdentifier = #"VerbCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

Unable to implement UIPopoverController delegation

I have the following view controller in my UIPopover:
#protocol StorePopoverDelegate
- (void)storeSelected:(NSString *)store;
#end
#interface StorePopoverViewController : UITableViewController
{
NSMutableArray* items;
}
#property (nonatomic, assign) id<StorePopoverDelegate> delegate;
#end
When an item is selected I want my delegate to get called:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (delegate != nil) {
[delegate storeSelected:[items objectAtIndex:indexPath.row]];
}
}
The delegate class that handles storeSelected is implemented:
-(IBAction)storesButtonClicked:(id)sender
{
storesPopoverViewController = [[StorePopoverViewController alloc] initWithStyle:UITableViewStylePlain];
storePopover.delegate = (id)self;
storePopover = [[UIPopoverController alloc] initWithContentViewController:storesPopoverViewController];
[storePopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
#pragma Store Popover Delegate Methods
- (void)storeSelected:(NSString *)store;
{
NSLog(#"%# was clicked", store);
[storePopover dismissPopoverAnimated:YES];
}
In my - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath the delegate is nil. I'm not sure why? I am assigning it.
In your storesButtonClicked: method you are setting the delegate of the storePopover (which is not even initialized at that point). You should be setting the delegate property of storePopoverViewController instead.
storePopoverViewController.delegate = (id)self;

How is my implemention of UITableViewController wrong?

This code copied anywhere else seems to work. It's just inside my app where it crashes. Any ideas why?
another .m...
#import "JEntryTableViewController.h"
#interface JCreateViewController () {
JEntryTableViewController *_tableView;
}
#property (nonatomic, strong) JEntryTableViewController *tableView;
#end
#implementation JCreateViewController
#synthesize tableView = _tableView;
- (id)init
{
self = [super init];
if (self) {
self.tableView = [[JEntryTableViewController alloc] initWithStyle:UITableViewStylePlain];
[self.view addSubview:self.tableView.view];
}
return self;
}
JEntryTableViewController.h:
#import <UIKit/UIKit.h>
#interface JEntryTableViewController : UITableViewController {
}
#end
JEntryTableViewController.m:
#import "JEntryTableViewController.h"
#interface JEntryTableViewController ()
#end
#implementation JEntryTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CountryCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60;
}
#end
I ran this as a quick test to make sure it was set up right, and to my surprise, when i scroll back to a cell I've already seen, it crashes and gives me a EXC_BAD_ACCESS error. Unfortunately the debugging area isn't giving me anything back that I can work with, and i really don't know what the problem is - it's such a basic, simple bunch of code. I don't know what to fix. It should work.
You way to implement the tableView may not the usual way we often do.
You can add the tableView directly into a ViewController without using another viewController inherit from UITableViewController.
What you should do is identically as what you did in JEntryTableViewController.
When come to the EXC_BAD_ACCESS problem, there are several solutions to find the exact problem.
1. EXC_BAD_ACCESS signal received
http://www.touch-code-magazine.com/how-to-debug-exc_bad_access/
at the right section of Xcode you can add these kind of break points, it may help you find the exception quickly in your case.
two things:
write <UITableViewDataSource, UITableViewDelegate> in
JEntryTableViewController.h file
write down the crash log here so that we can easily solve your problem.

Create a two tableview list using one TableViewController class

I want to do an sample application where in a view i have two buttons one is COUNTRY and another is STATE.
when i click on a country button the country list should appear in a tableview class like a popup and when i click on state button state list should appear in a tableview like popup,So how can i do this please suggest with sample code.
NOTE:I should use only one TableViewcontroller class for both country and state Data list.
Here is the Code:
RootViewController.h
#interface RootViewController : UIViewController {
UIButton *btnCountry;
UIButton *btnState;
NSMutableArray *tempArray;
NSMutableArray *countryArray;
NSMutableArray *stateArray;
IBOutlet UITableView *tempTable;
}
#property (nonatomic,retain) UIButton *btnCountry;
#property (nonatomic,retain) UIButton *btnState;
#property (nonatomic,retain) NSMutableArray *countryArray;
#property (nonatomic,retain) NSMutableArray *stateArray;
#property (nonatomic,retain) NSMutableArray *tempArray;
#property (nonatomic,retain) UITableView *tempTable;
- (IBAction) showState:(id)sender;
- (IBAction) showCountry:(id)sender;
#end
RootViewController.m
#implementation RootViewController
#synthesize btnState,btnCountry, stateArray,countryArray,tempArray;
#synthesize tempTable;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
tempTable.hidden = YES;
countryArray = [[NSMutableArray alloc]initWithObjects:#"India",#"Pakistan",#"USA",nil];
stateArray = [[NSMutableArray alloc]initWithObjects:#"Gujarat",#"Maharashtra", #"Karnataka",nil];
tempArray = [[NSMutableArray alloc]init];
}
- (IBAction) showCountry:(id)sender
{
btnCountry = (UIButton *)sender;
tempArray = countryArray;
[tempTable reloadData];
if([btnCountry isSelected])
{
tempTable.hidden = YES;
btnCountry.selected = NO;
}
else
{
tempTable.hidden = NO;
btnCountry.selected = YES;
}
}
- (IBAction) showState:(id)sender
{
btnState = (UIButton *)sender;
tempArray = stateArray;
[tempTable reloadData];
if([btnState isSelected])
{
tempTable.hidden = YES;
btnState.selected = NO;
}
else
{
tempTable.hidden = NO;
btnState.selected = YES;
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [tempArray 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:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [tempArray objectAtIndex:indexPath.row];
return cell;
}
#end
The question is not clear enough ,, what did you try? ..
But, You can use UIPopOverController for that
see
THIS LINK
Or Just a Static UiTableView in the same Nib file ,, make it hidden when you don't need it .
You can use One Tableview for this: Here i am attaching only the logic.
In viewdidload,
There will be two arrays countryArray and stateArray.
There will be a third array : tempArray
there are two buttons: button1 and button2
tableview.hidden=YES;
in button1Action assign the countryArray to tempArray and also [tableview reload]
in button2Action assign the stateArray to tempArray and also [tableview reload]
then in tableview delegates,
(NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [tempArray count];
}
and then in
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
use tempArray.......
}
try this...and if you want more detailed pls inform....
Take Two tableViews and two Buttons.
Place each tableview below each of the button.
Initially both the TableViews are hidden. When the Button is clicked show the TableView with Animation.
I think you should only use one TableViewController but with different data sources.

How to create custom uiviewtable?

I'm working on an app for my client. I'm stuck now.
I don't know how to explain. But i make a photoshop image of it.
http://i.stack.imgur.com/cV4mL.jpg
user tap on parent tablecell.
execute didSelectRowAtIndexPath:(NSIndexPath *)indexPath. User select cell.
parent cell update.
Anyone know what is this called?
Do you have tutorial for it?
// FirstViewController (1st in your Photoshop-design)
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.cell = [tableView cellForRowAtIndexPath:indexPath];
[self.navigationController pushViewController:secondViewController animated:YES];
}
...
-------------------------
// SecondViewController.h
#interface SecondViewController : UITableViewController {
UITableViewCell *cell;
}
#property (nonatomic, retain) UITableViewCell *cell;
-------------------------
// SecondViewController.m
...
#synthesize cell;
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.cell.detailTextLabel.text = #"Something";
[self.navigationController popViewControllerAnimated:YES];
}
...
Use UINavigationController with UITableViewController as its root controller and when diving deeper, instantiate a different UITableViewController for that and push it on the navigation stack. Popping is similar.
There are good examples for UINavigationController accessible from Apple's docs.