how to populate an array or any object from one view controller to another when we present the view using story board - iphone

I have implemented my iphone app using story board
In my app *i need to present a view from one view to another view not the pus*h,
I have created a screen in story board xib for the second view .
i set up the connection for button in the first view to the second view with 'present' not pust.
Now i need to populate an array to the second view which was presented
i tried following ways but not work out
1:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UIButton *)sender
{
//Populate detail to BuyView mail page
if ([segue.id
entifier isEqualToString:#"BuyView"])
{
BuyViewController *destViewController = segue.destinationViewController;
destViewController.itemDetailsArray = [_itemDetailsArray objectAtIndex:sender.tag] ;
}
}
2:
- (IBAction)buyItemClick:(UIButton *)sender
{
BuyViewController *destViewController = [[BuyViewController alloc] init];
destViewController.itemDetailsArray = [_itemDetailsArray objectAtIndex:sender.tag] ;
}

On top of what #rdelmar has stated you are passing an object of which may or may not be an array.
Which in turn would mean
destViewController.itemDetailsArray
Would be pointing to an object which may not be an array.
I think what you want to do is
destViewController.itemDetailsArray = _itemDetailsArray;

Related

push from a side bar menu to another view controller in ios

I use in my application, the side bar menu like in facebook, so I have different cells in this menu, what I want is to when click on a cell push me to another view controller. I face a problem here which is: the menu is a table view which I don't have it in storyboard, I use some classes from this site:github
and I've stucked here, in my application I use a storyboard, but this menu is programmed with code, and doesn't have a view in stroyboard,
in the didSelectRowAtIndexPath method: I use like this
for(int j=0; j< 9 ; j++)
{
if(indexPath.row == j)
{
DetailsSidebarViewController *essayView = [[DetailsSidebarViewController alloc] init];
essayView.detailItem = [jsonResults objectAtIndex:j];
NSLog(#"%#=%d",essayView.detailItem,j);
}
}
and I create a DetailsSidebarViewController as the new view controller when I push from menu item. in this class, I create a method to configure the view, and just I echo the result:
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
NSLog(#" %# ", self.detailItem);
}
}
the result is true like I want, but I want to push to another view controller, in fact nothing is happened when I click on an item into the menu.
How can I create the new view controller in storyboard? if the menu has not a storyboard, and how can I connect them with segues?
In fact, I am blue with it, please help!!
You should make an instance of the App Delegate class in the Side Menu view controller, and push it from there. You must have a reference to the Side Menu View and a reference to the Center View! Import your App Delegate into the Side Menu controller, and in the didSelectRowAtIndexPath, use:
DetailsSidebarViewController *essayView = [[DetailsSidebarViewController alloc] init];
essayView.detailItem = [jsonResults objectAtIndex:indexPath.row]; // note that you don't need the for loop to know what object you need
AppDelegate* myAppDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[myAppDelegate.sideMenuViewController toggleSideMenu]; // the idea here is that you have to close the side menu, i.e. it must dissapear
[myAppDelegate.centerViewController.navigationController pushViewController:essayView animated:YES];
This is all the code you need.
If I may, as a piece of advice, use Mike Frederik's MFSideMenu instead of the library you're using. In my opinion, it has a more simple and a more straightforward implementation, just look into the README file, everything is explained pretty simple, and it has exactly the code you need!
Hope this helps, good luck!

Creating a custom view in Interfacebuilder and using that in code

I have made a view in the application that shows a UITableView. It will be full of results (obviously) almost all the time, however when it does not have any results I want to show another view that inform the user about how he/she could populate the table.
I want to design that view in the interfacebuilder. I will have to check in the code whether the datasource is empty or not to toggle between the two different nibs. How do I instantiate and configure a view made in Interfacebuilder?
The easies way to do this is by adding the view in xib normally and make it visible
Design your both views, the table view and the other view, give the tableView a tag of 111 for example and give the otherview another tag 222 for example
Now in viewDidLoad
Get both the views
UIView *noDataView = [self.view viewWithTag:222];
UITableView *tableView = [self.view viewWithTag:111];
//Hide both of them or only the noDataView until you know if you have data from the dataSource or not
Check for your data source
//hasElements do you have any element to show?
if(hasElements)
{
noDatView.hidden = YES;
tableView.hidden = NO;
}
else
{
noDatView.hidden = NO;
tableView.hidden = YES;
}
You can load nib file based on condition.You can write category as follows:
self.view = (UIView *)[self loadNib:#"SecondView" inPlaceholder:self.view];
- (UIView *)viewFromNib:(NSString *)nibName
{
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];
for (id view in xib) { // have to iterate; index varies
if ([view isKindOfClass:[UIView class]]) return view;
}
return nil;
}
- (UIView *)loadNib:(NSString *)nibName inPlaceholder:(UIView *)placeholder
{
UIView *nibView = [self viewFromNib:nibName];
[nibView setFrame:placeholder.frame];
self.view = nibView;
//[self.view insertSubview:nibView aboveSubview:placeholder];
//[placeholder removeFromSuperview];
return nibView;
}
The other answers give you possible technical solutions but I would propose that if you are using the standard Apple design guidelines, you probably don't even need to worry about it. For instance, somewhere on your screen you should have a bar button item with the identifier "Add" (which shows the plus icon). Then rather than giving a long (often poorly localised) description of how to add items, just have a header for an empty section which says "No items" replacing items with whatever pluralised noun is appropriate for your table's items. For example, for an Archery related app I am working on:
Notice how the Edit button is currently disabled too, thus no explanation is needed as the only thing they can do at this point is tap the Add button (screenshots on the Appstore will have shown them what they can expect to see after this point).

perpareForSegue - Passing image name - Blank at First

I have a thumbnail view controller with two thumbnails. Each have an IBAction setting the image name. The next view should display the full image.
The first time I select a button, the new view opens but is completely blank. I go back to the previous screen (navigation controller) and select the button again and the full image screen shows with the correct full image.
Back out, select the second button and the full image of the first button is displayed.
It appears that the full image is off by one iteration.
Below are some code snippets.
thumbnailViewController.M
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
fullImageViewController *targetVC = (fullImageViewController*)segue.destinationViewController;
targetVC.fullImageName = _imageName;
}
- (IBAction)running1 {
_imageName = #"img_running1.png";
}
- (IBAction)running2 {
_imageName = #"img_running2.png";
}
fullImageViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
_fullImage.image = [UIImage imageNamed: _fullImageName];
}
Any suggestions.
I'm guessing that you have both the IBAction and the Segue hooked up to your buttons? If so this is your issue. The segue occurs before the IBAction. The solution is instead of having the button hooked up to the segue have the IBAction perform it.
- (IBAction)running1 {
_imageName = #"img_running1.png";
[self performSegueWithIdentifier:#"yourSegue" sender:self];
}
This will correct the order by giving you control. otherwise I believe its segue then action.

iPhone App Dev - Return Values From Child To Parent View

I have a parent view controller which loads a child view using presentmodalview. To be precise, this child view is a login page.
The login page has two textfields (email and password) and a 'login' button. When the login button is pressed, providing the data input is valid, I would like to send the user details to the root view controller who will then create a user object if the user exists or otherwise present a uialertview indicating to the user that invalid details have been entered.
In my child view I have the following function linked to the 'login button':
-(IBAction) signIn:(NSString*)userEmail with:(NSString*)userPassword{
//takes text field values and instantiates a dbConnector object to
//check to see if user exists - must also post uialertview if user details incorrect
NSString* uName = [email text];
NSString* pword = [password text];
userDetails = [[NSMutableArray alloc] initWithObjects:uName, pword, nil];
NSLog(#"%#", userDetails);
}
What is the best way to pass the userDetails array back to the rootviewcontroller after the button has been pressed?
SOLUTION - Protocols & Delegates
Create UserDeatails array in the ParentViewController and Set its Value when the Button is Pressed in ChildViewController.
But you have to create object of the ParentViewController as like;
ParentViewController *parentView = [[ParentViewController alloc] initWithNibName:#"ParentViewControllerName" bundle:nil ];
parentView.userDeatails = userDetails_in_ChildView;
You need to pass your user object before pushing or present another view controller.
Refer this answer. Hope this help.
Just declare a variable into Your Delegate file like
String *strUsername;
String *strPassword;
And also create property and synthesize for that..
then after create a object of your delegate where ever you want like this..
NavigationBarAppDelegate *appDelegate= (NavigationBarAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.strUsername = uName;
appDelegate.strPassword = pword;
now this value is get every war..just get it creating delegate object like above...
NavigationBar is a name of my application.

Is it possible to select a row in a **previous** UITableview

Is it possible to select a row in a previous UITableview.
I provided image samples to get a more clear picture of what is happening exactly.
http://img186.imageshack.us/img186/933/picture8a.png
http://img405.imageshack.us/img405/9327/picture9d.png
http://img200.imageshack.us/img200/5386/picture10thm.png
At the morning workout screen , one can select a row and behind it so it will play a Movie.
If the movie plays you can press the secondbutton and it will take you to the final table.
If you press the backbutton you will simply return to the previous screen.
Now here is where my problem lies.
If i'm in my final screen after pressing the secondbutton and I press on the backbutton it would be great if it could play the previous video( in other words the video connected to the previously selected cell)
So if it's possible for me to create a function or some sort of action that can actually select the previously selected row from the first field ( for instance Lunge Forward in this example ).
perhaps with some like
previousRow = [ self.tableView indexPathForSelectedRow];
[self tableView:[self tableView] didSelectRowAtIndexPath:previousRow];
just doing something there
Even if it's not possible I would appreciate it if someone would let me know.
edit:
Here is some code behind the cell when it's going to play a video
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the dictionary of the selected data source.
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//check to see if video must be played
NSString *playVids = [dictionary objectForKey:#"playVids"];
finalscreen = [dictionary objectForKey:#"finalScreen"];
if(playVids == nil )
{
if(CurrentLevel != 0 )
{
if( finalscreen == nil )
{
NSString *movies = [dictionary objectForKey:#"movieID"];
NSURL *movie = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:movies ofType:#"m4v"]];
theMovie = [[MPMoviePlayerController alloc] initWithContentURL:movie];
[theMovie setOrientation:UIDeviceOrientationPortrait animated:NO];
[theMovie setScalingMode:MPMovieScalingModeAspectFit];
theMovie.backgroundColor = [ UIColor whiteColor];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:theMovie];
[theMovie play];
[self getToolBarStuff];
lblTitle.text = [dictionary objectForKey:#"Title"];
[[[UIApplication sharedApplication]keyWindow]addSubview:toolbar2];
[[[UIApplication sharedApplication]keyWindow]addSubview:imageView];
[[UIApplication sharedApplication]keyWindow]addSubview:lblTitle];
}
}
else
{
WebViewController *web = [[WebViewController alloc] initWithNibName:#"WebView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:web animated:YES];
[web release];
}
}
else {
//Prepare to tableview.
rvController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
rvController.CurrentLevel += 1;
//Set the title;
rvController.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.navigationController pushViewController:rvController animated:YES];
rvController.tableDataSource = Children;
[rvController release];
}
}
I get my info/feeds from a dictionaryfile and also different tags in my dictionary tell my tableview when to play the video and when not( playVids ).
so to be exact I have a start screen which brings you to a second screen and that one brings you to the morning workout screen and from there if you click a cell it will play a (different with every cell) video. I can't use the standard design from apple(with the backbutton above) since this assignment specifically asks to use their own design.
That's the reason why i created my own tabbar and backbutton.
My backbutton looks like this
-(void)back_clicked:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
CurrentLevel--;
switch( CurrentLevel ) {
case 0;
[toolbar removeFromSuperView];
default:
break;
}
}
So if I'm in the last screen I just pop that screen to return to my previous one( the morning workout). And what actually has to be done is pop that screen and play the last video. I thought I could do that by popping the last screen and then selecting the previously clicked cell in morning workout.
Any thoughts on that.
I am not sure I understand your problem exactly here. Can you show a bit more code? You have 3 view controllers, right? Are you using a standard navigation controller pattern with push/pop to get from one to the other? It looks like maybe you aren't since the buttons are in an odd layout.
If you are then pressing the back button can just pop view 3 and go back to view 2 naturally (it will still be there, so the video should still be playable) so I don't see why you need to mess with the table in view 1 in order to find that and make it show again. You should just be able to hook into viewWillAppear and do the same thing you did when coming from view 1.
And if you aren't using a standard navigation controller pattern then maybe this is the problem. From a UI perspective you probably should do that anyway - people will expect a standard back button in the title bar.
I am pretty sure your problem is soluble anyhow - you can always pass object references from one view to the other when creating them for example - but I don't think you need to resort to the method you have in mind.
edit: reading the additional detail I see you are indeed using push/pop. So you have a stack of views, and when one is popped it uncovers the one beneath it, right? It should therefore be possible to do what you want by implementing the viewWillAppear or viewDidAppear methods in your controller. When your final screen is popped, if I understand correctly it will uncover the view which is able to play the movie. Your viewcontroller will get the viewWillAppear / viewDidAppear messages in that case - by maintaining state and receiving those messages you can then implement logic to decide whether or not you need to play the movie. Rather than call the didSelectRow. method again you could perhaps put the movie play stuff in its own method so you can call from either viewDidAppear or didSelectRow...
I also am not sure that I fully understand your question either but it sounds similar to a problem I was working on recently. Check out this post on using up down arrows to move through the parent table while in a detail view. My app was based on the same sample code so you should be able to get this to work without much trouble.
Up/down arrows in nav bar of detail view to page through objects in parent table