Sending objects between viewcontrollers that are bundled with navigationcontroller - iphone

I have two viewcontrollers that are both bundled with navigationcontrollers. Im trying to send an object from one viewcontroller to the other. I use the code below in the didselectrow of the table:
UIViewController *serviceTable = [self.storyboard instantiateViewControllerWithIdentifier:#"navigationServiceNews"];
((TableServiceNews*)serviceTable).service_ID = [ServiceID objectAtIndex:indexPath.row];
[self.slidingViewController anchorTopViewOffScreenTo:ECRight
animations:nil onComplete:^{
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = serviceTable;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];
}];
The identifier that im using (navigationServiceNews) points to the navigationcontroller that is bundled with the destination viewcontroller.
While using this identifier, the app crashes because obviously instantiateViewControllerWithIdentifier returns a veiwcontroller not a navigationcontroller.
When i change the identifier to the ID of the destination viewcontroller,every works fine but i lose the navigationBar on the header which is very important to my project(it is the reason i decided to bundle the viewcontrollers with navigationcontroller).

If "navigationServiceNews" is the identifier you assigned to the navigation controller, then instantiateViewControllerWithIdentifier: will instantiate a navigation controller not a UIViewController, so that's not your problem. You problem is on the next line -- I assume that serviceID is a property on TableServiceNews not the navigation controller, so you need to get ahold of that controller using topViewController.
UINavigationController *serviceTableNav = [self.storyboard instantiateViewControllerWithIdentifier:#"navigationServiceNews"];
TableServiceNews *serviceTable = serviceTableNav.topViewController;
serviceTable.service_ID = [ServiceID objectAtIndex:indexPath.row];
[self.slidingViewController anchorTopViewOffScreenTo:ECRight
animations:nil onComplete:^{
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = serviceTable;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];
}];

Related

ECSlidingViewController How to go from one TopViewController to another TopViewController using animation in iOS

I am using ECSlidingViewController in my app for Facebook style swipe effect. I have 2 TopViewControllers, one left and one right side view controller and one initviewcontroller which is a slidingviewcontroller subclass.
1. InitViewController:ECSlidingViewController
2.MainViewController (TopViewController)
3.LeftMenuViewContrller (UIViewController)
4.RightMenuViewController (UIViewController)
5.DetailViewController (TopViewController)
I have tableview on my MainViewController which contains the calendar events. The problem is that I want to go to MainViewController to DetailViewController by clicking the event in tableView:didSelectRowAtIndexPath: methods to show the events details which is another topview controller with some animation( which I am unable to get so far). I am using following code which is getting me to the DetailViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailsViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"details"];
self.slidingViewController.topViewController = newTopViewController;
[self.slidingViewController resetTopView];
}
this is my viewDidLoad method
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.layer.shadowOpacity = 0.75f;
self.view.layer.shadowRadius = 10.0f;
self.view.layer.shadowColor = [UIColor blackColor].CGColor;
if (![self.slidingViewController.underLeftViewController isKindOfClass:[LeftViewController class]]) {
self.slidingViewController.underLeftViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Left"];
}
if (![self.slidingViewController.underRightViewController isKindOfClass:[RightViewController class]]) {
self.slidingViewController.underRightViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Right"];
}
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
}
I want to get the animation like the UINavigationController or Modal style
[self.navigationController pushViewController:newTopViewController animated:YES];
or
[self presentViewController:newTopViewController animated:YES completion:nil];
please help. thank you.
Are you using Storyboard? Could you perform a Segue? In the storyboard setup the name and the link and style as Modal along with the Transition.
In your DidSelectRowAtIndex put this
[self performSegueWithIdentifier:#"eventDetail" sender:#(indexPath.row)];
Then declare this method
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"eventDetail"])
{
DetailsViewController *destViewController = segue.destinationViewController;
destViewController.eventRow = sender;
}
// You can test for other Segue names here
}
Then in the DetailsViewController.h put
// Allows sending View Controller to give this controller data
#property (nonatomic, strong) int *eventRow;
And in the .m put
#synthesize eventRow;
Now in your DetailsViewController it should animate to it and the sliding will be disabled (unless you declare all the ECS bits as normal). You also have an Int eventRow which tells you which cell was clicked.
You can create a back button and do this;
[self dismissViewControllerAnimated:YES completion:nil];
EDIT
OR you could try this but I am not sure if it will animate plus you need to figure out how to pass stuff, maybe a combination of the two...
UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"eventDetail"];
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = newTopViewController;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];

scrollview with multiple UIViewController

I'm trying to figure out the best way to implement multiple UIViewControllers within a UIScrollView. For now, I initiate my UIViewController manually and add it as a Subview to Scrollview. This works fine, but the scrollview doesn't show more than ONE UIViewController even after scrolling to the right. Any idea why this might happen? Here's my code:
DTArticle *article = [self.articles objectAtIndex:0];
DTArticle *article2 = [self.articles objectAtIndex:1];
UIStoryboard *mainStoryBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
DTArticleViewController *controller = [mainStoryBoard instantiateViewControllerWithIdentifier:#"DTArticleViewController"];
DTArticleViewController *controller2 = [mainStoryBoard instantiateViewControllerWithIdentifier:#"DTArticleViewController"];
controller.article = article;
controller2.article = article2;
[self.parentScrollView addSubview:controller.view];
[self.parentScrollView addSubview:controller2.view];
self.parentScrollView.contentSize = CGSizeMake(self.parentScrollView.frame.size.width
* 2, self.parentScrollView.frame.size.height);
self.parentScrollView.showsHorizontalScrollIndicator = YES;
[self.parentScrollView setPagingEnabled:YES];
[self.view addSubview:self.parentScrollView];
From the code you've added, both views are at the same location, one on top of the other. When you add the second view you should change its frame origin to position it next to the first view.

Switching views with ECSliding without navigation menu

I'm using ECSlidingViewController.
In the sample project i added a button on the First view with an IBAction
I want the button on the First view to go to the second view (without using the slide out navigation).
- (IBAction)btnPressed:(id)sender {
UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondTop"];
[self.slidingViewController anchorTopViewOffScreenTo:ECRight animations:nil onComplete:^{
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = newTopViewController;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];
}];
}
With this code it only goes to the navigation slide out menu and doesn't go to the Second
Don't always use self.slidingViewController. It's a derived property, not a static value. So what's happening is that you replace the first view with the second view and then the first view can't get the sliding controller any more (you broke its reference). So, do this instead:
- (IBAction)btnPressed:(id)sender {
ECSlidingViewController *slidingViewController = self.slidingViewController;
UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondTop"];
[slidingViewController anchorTopViewOffScreenTo:ECRight animations:nil onComplete:^{
CGRect frame = slidingViewController.topViewController.view.frame;
slidingViewController.topViewController = newTopViewController;
slidingViewController.topViewController.view.frame = frame;
[slidingViewController resetTopView];
}];
}

ECSliding, change underLeftViewController

I'm using ECSliding and I have this problem!
In my project there are this files:
InitViewController (ECSlidingController)
FirstViewController (UIViewController)
SecondViewController (UIViewController)
LeftMenuViewController (UIViewController)
LeftMenuTwoViewController (UIViewController)
I use InitView to instatiate my FirstView as the topview.
Sliding right shows LeftMenuViewController, that has a button, if pressed change topview to SecondViewController. I would like to know if is it possible to use LeftMenuTwoViewController as the underLeftViewController of SecondView. Also I want a button in LeftMenuTwo that changes topView to FirstView.
I want a FirstView with underLeftViewController as LeftMenuViewController, and SecondView with underLeftViewController as LeftMenuTwoViewController. Each menu have a button that change the topView to the other one with different underLeftViewController.
I did this:
SecondViewController *second = [self.storyboard
instantiateViewControllerWithIdentifier:#"SecondTop"];
[self.slidingViewController anchorTopViewOffScreenTo:ECRight
animations:nil
onComplete:^{
self.slidingViewController.topViewController = second;
[self.slidingViewController resetTopViewWithAnimations:nil
onComplete:^{
LeftMenuTwoViewController *newUnderLeftVC = [self.storyboard
instantiateViewControllerWithIdentifier:#"LeftTwo"];
self.slidingViewController.underLeftViewController = newUnderLeftVC;
}];
}];
But when I push the button the topView starts the bouncing animation by sliding right but never comes back again and immediatly after the TopView goes off screen the underLeftViewController becomes blank. Anyone know why?
Download: My Project
Change the method to this:
-(IBAction)openSecond:(id)sender
{
SecondViewController *second = [self.storyboard instantiateViewControllerWithIdentifier:#"Second"];
ECSlidingViewController *slideController = self.slidingViewController;
[slideController anchorTopViewOffScreenTo:ECRight animations:nil onComplete:^{
slideController.topViewController = second;
[slideController resetTopViewWithAnimations:nil onComplete:^{
LeftMenuTwoViewController *newUnderLeftVC = [self.storyboard instantiateViewControllerWithIdentifier:#"LeftTwo"];
slideController.underLeftViewController = newUnderLeftVC;
}];
}];
}
The problem was that when the view removes itself as the top view controller, calling self.slidingViewController no longer returns a valid instance (it returns nil).

pushViewController from another class

I want to push a view controller from my FirstViewController to load BookDetailsViewController. here's the setup I currently have.
// FirstViewController:(this is inside a uinavigationcontroller)
-(IBAction)viewBookDetails:(id)sender
{
NSLog(#"woo");
BookDetailsViewController *bdvc = [[BookDetailsViewController alloc] init];
[self.navigationController pushViewController:bdvc animated:YES];
}
==============================================================
// BookScrollViewController: (where the button is located)
[book1UIButton addTarget:self action:#selector(viewBookDetails:)
forControlEvents:UIControlEventTouchUpInside];
-(void)viewBookDetails:(id) sender
{
FirstViewController *fvc = [[FirstViewController alloc] init];
[fvc viewBookDetails:sender];
}
==============================================================
//how BookScrollViewController is created
BookScrollViewController *controller = [bookViewControllersArray
objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
NSString *bookTitle = #"ngee";
controller = [[BookScrollViewController alloc]initWithBook:bookTitle
imageNamesArray:imgDataArray pageNumber:page totalResult:[newReleasesArray
count]];
[bookViewControllersArray replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (nil == controller.view.superview) {
CGRect frame = bookScroll.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[bookScroll addSubview:controller.view];
}
when I tap the button in BookScrollViewController it calls the IBAction I have in FirstViewController coz it prints my nslog but it's not loading pushing the BookDetailsViewController to the navigation stack.
I tried assigning a button from FirstViewController to call the IBAction and it loads just fine. So, how can I successfully call the IBAction from FirstViewController using the button from BookScrollViewController?
thanks!
When you are assigning an action in the following way:
[book1UIButton addTarget:self action:#selector(viewBookDetails:) forControlEvents:UIControlEventTouchUpInside];
You say that (current object: self) BookScrollViewController *self will respond to events UIControlEventTouchUpInside of book1UIButton. That means when user tap on button method viewBookDetails of object of class BookScrollViewController will be called.
As you mentioned in your question you have defined and implemented such method in FirstViewController.
Now you should
implement that method in BookScrollViewController that will push new controller onto navigation stack, or
set another object that will respond on that button event, that object can be of class FirstViewController, for example, [book1UIButton addTarget:self.firstViewController action:#selector(viewBookDetails:) forControlEvents:UIControlEventTouchUpInside];
When you do this:
FirstViewController *fvc = [[FirstViewController alloc] init];
you obviously create a new instance of FirstViewController. That new instance is not in a UINavigationController, so you can't push a new viewController onto its navigationController property.
What you probably want to do is reference the existing instance of FirstViewController and call the method on it instead of creating a new instance of it.