how can I handled event when Left menu hided. For example:
On home screen I have a table with items
On left side Menu I have a category list, when I selected the item on the left menu I assign value of a global variable and go to back to main top View
where I want run new query and update tableView items.
Thanks!
You should implement the following method in your category list controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
For instance, my LeftMenu was basically a UITableviewController (Same as in the ECSlidingViewController basic demo), I needed to filter the items shown in TopViewController based on what row was tapped in the LeftMenu, here is how I did it:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
//To stop TopViewController from being reset each time.
ECSlidingSegue *slidingSegue = (ECSlidingSegue *)segue;
slidingSegue.skipSettingTopViewController = YES;
//getting the dataobject associated with the selected table row
NSIndexPath *selectedIndexPath = [_tableView indexPathForSelectedRow];
MyDataObject *dataObject = [_dataArray objectAtIndex:selectedIndexPath.row];
//Digging down into the hiearchy to get to my required view
UITabBarController *tabBarController = (UITabBarController *)[[segue destinationViewController] topViewController];
UINavigationController *navigationController = [[tabBarController viewControllers] objectAtIndex:0];
MyFilteredListViewController *filteredListViewController = (MyFilteredListViewController *)[navigationController topViewController];
//Calling a method on the viewcontroller
[filteredListViewController filterForDataObject:dataObject];
}
So I had to dig down a little to find the viewcontroller that I specifically needed because MyFilteredListViewController was inside a Navigation Controller which was in turn a child of TabBarController which was then set as the TopViewController of the ECSlidingViewController.
It should be more straight forward to access viewcontrollers if they are not nested in a complex manner :)
Once you have the view controller that you require then you can call a method on it (as I did) or you could access a variable property and set its value.
You will have to import "ECSlidingSegue.h" into your category list controller.
Hope this helps!
If I understood correctly what you want to do, you can set your topviewcontroller as delegate of the sliding ECSlidingViewController
Then on your topviewcontroller you can implement the optional
- (id<UIViewControllerAnimatedTransitioning>)slidingViewController:(ECSlidingViewController *)slidingViewController
animationControllerForOperation:(ECSlidingViewControllerOperation)operation
topViewController:(UIViewController *)topViewController;
That's a good point to perform any custom action you want before the animation of the topviewcontroller occurs.. if you don't want custom animations/transitions to happen, remember to return nil after your custom code.
Related
I have view which contains a collection view. I have added this collection view programatically (in viewDidLoad) - so that is not on the storyboard. This collection view contains several cells. When a user clicks on one of the cells in the collection view, I want to segue to a different view controller (that I plan to add on the storyboard). My question is - since the collection view is not on storyboard, how can I segue out of that? Or is there other way to accomplish that.
Some updates to the original question above:
In Parent View Controller, I do the following:
//Layout for the collection view
CDLayout *cdLayout = [[CDLayout alloc] initWithItemSize:CGSizeMake(cardWidth, cardHeight) withItemInsets:UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset) withInterItemSpacingX:8.0f withTopMargin:margin withLeftMargin:margin withBottomMargin:margin withRightMargin:margin shouldRotate:NO];
//This is the collection view controller
CDLineLayoutViewController *cdLineVC = [[CDLineLayoutViewController alloc] initWithCollectionViewLayout:cdLayout withItemCount:12 ];
// add the collection view controller to self - the parent
[self addChildViewController:cdLineVC];
[cdLineVC didMoveToParentViewController:self];
// add collectionView as a subview
[self.view addSubview:cdLineVC.collectionView];
The collectionView has 12 cards. When a user clicks on one of the cards I want to move to another view controller.
As you can see the collection view is not on the storyboard. So, is there a way to create a segue?
BTW, one option is what Taseen suggested below. I tried that and it is working. But as I understand it is not actually a "segue."
Can you please show us any code you have written
What i have understood from your question is that you have added collection view in viewDidLoad. and i believe you have set the delegate of collection view to self, So in
didSelectItemAtIndexPath method you can write this code
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//From indexpath.item, you know which cell was clicked
//using switch method
switch (indexPath.item) {
case 0:
//You Can push the view controller from here
//You need to import the header file of that View controller
DestinationViewController *destinationView;
//if the self controller in which the collection view is shown is embedded in Navigation controller,
//you can push using
[self.navigationController pushViewController:destinationView animated:YES];
//if it is not embedded, use modal segue
[self.modalViewController presentModalViewController:destinationView animated:YES];
break;
default:
break;
}
}
EDIT: The segue you will create on the storyboard from your ParentViewController to DestinationController will have segueIdentifier property. like shown below
then in didSelectItemAtIndexPath instead of pushing the controller you can use this code
[self performSegueWithIdentifier:#"collectionViewSegue" sender:self];
you can also configure the destination view controller using prepareForSegue method..
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DestinationViewController *targetVC = (DestinationViewCOntroller *)segue.destinationViewController;
//if you pass anything you can do it here
//if to set any public variable for example image for the imageview
targetVC.cardImageView.image = [UIImage imageNamed:#"queen.png"];
}
This method will be in your parent controller.
Create a new segue by ctrl-click on the initial viewController and drag to the destination viewController. Don't forget to set the segue identifier.
than overwrite the -(void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender method.
I have two Views part of a NavigationController hierarchy, one that displays a list of items and the second allows you to edit an item or add a new one.
On the parent view I have an add button on the right of the navigationbar once pressed performs a segue with identity "AddChild". Also, when the user taps on a table item, I perform another segue with identity "EditChild", all set up in storyboard.
In the case the user arrives at the parent view (with the list of items) but no items exist yet, I want to programatically perform the "AddChild" segue, so I added the following code in viewWillAppear: of the parent viewcontroller.
// if there are no children, send user to add screen
if (self.childListData.count == 0) {
[self performSegueWithIdentifier:#"AddChild" sender:self];
}
The child viewcontroller loads fine, but the navigation items are still of the previos view (a back button and an add button instead of a back button and a save button).
This is my prepareForSegue: method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get a reference to our detail view
ChildDetailTableViewController *childDetail = (ChildDetailTableViewController *)[segue destinationViewController];
// Pass the managed object context to the destination view controller
childDetail.managedObjectContext = managedObjectContext;
// If we are editing a child we need to pass some stuff, so check the segue title first
if ([[segue identifier] isEqualToString:#"EditChild"])
{
// Get the row we selected to view
NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row];
// Pass the child object from the table that we want to view
childDetail.currentChild = [childListData objectAtIndex:selectedIndex];
}
}
I'm not sure what I'm missing so if anyone can help, I'd appreciate it.
I have a TableViewController with multiple cells(detail disclosure) each associated with unique data(eg. title/details). When I click one of the cells another ViewController gets loaded(via modal or push segue) and should display the data depending on which cell was clicked.
Simple Eg:
Each Cell of TableViewController are associaed with separate urls. When I click one of the cells(detail disclosure), the next ViewController that contains a WebView should open the web page corresponding to the url of the cell clicked.
How can we achieve that?
One way of accessing the data is to use the following inside the prepareForSegue method:
NSIndexPath *indexPath = tableView.indexPathForSelectedRow;
This will give you the access to the selected row (cell) of the table so that you know which item your user has selected.
Then extract any data you need and pass it to the destination view controller using the prepareForSegue method as shown in the other answer.
First, you need to set the identifier of each segue (in the storyboard, just click on the segue and set it in the Attributes Inspector).
Then, in your UITableViewController subclass, you need to override prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"yourSegueIdentifier"] ) {
UIViewController *viewController = segue.destinationViewController;
viewController.yourVariable = yourData;
}
}
I am currently trying to copy an array I have to a new view that I am creating programmatically. I actually have found how to do this with normal navigation controller syntax. My issue is I'm using the new storyboard and I don't know the syntax to do the same thing. Here is the code I have..
CustomerListViewController *second = [[CustomerListViewController alloc] initWithNibName:#"CustomerListViewController" bundle: nil];
[second setValue:customerList.list];
// [self.navigationController pushViewController:second animated:YES];
[self performSegueWithIdentifier:#"LoginSegue" sender:self];
as you can see, I am programmatically creating the second view controller and storing the local array customerList.List to the created view controller's array variable. The next step is to open the new created view. The line commented out is the syntax to open the view under a navigation controller. The line below is the storyboard way, but minus specifying the view I created. I need to know the syntax for the storyboard to do the same thing as the navigation controller.
It does not make sense to create your own instance of CustomerListViewController here if you're using segues. The segue itself will create the view controller from the storyboard and the instance you have created here will do nothing.
Instead, just call performSegueWithIdentifier:sender: here. Then implement the prepareForSegue:sender: method like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"LoginSegue"]) {
CustomerListViewController *destinationController = (CustomerListViewController *)segue.destinationViewController;
[destinationController setValue:customerList.list];
}
}
I hope I'm not asking something that's been already answered (but I found no answer to this, so hopefully I'm not).
I have an app in the current xcode version, using segues and navigationController. I need to pass data from one view to the other - what's the easiest way to do this? I ran onto some sharedData thing that could be possibly hooked onto the performSegueWithIdentifier method but don't know how to use it (or whether it is the right choice to do it like this).
Thanks
A segue has two view controllers: sourceViewController and destinationViewController. When UIKit executes a segue, it sends a prepareForSegue:sender: message to the source VC. You can override that method in your view controller subclass to pass data to the destination VC.
For example, suppose you have a master view controller with a table view of movies, and when the user clicks a row in the table view, you want to segue to a detail view controller for the movie.
#implementation MasterViewController
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DetailViewController *detailVC = segue.destinationViewController;
NSIndexPath *selectedPath = [self.tableView indexPathForSelectedRow];
detailVC.movie = [self movieForIndexPath:selectedPath];
}
This is explained in the Introducing Interface Builder Storyboarding video from WWDC 2011.
It's also worth noting that when the segue's origin is a table view cell, or the accessory button of a table view cell, the sender argument of prepareForSegue:sender: is the table view cell.
I think the best way is to import header for the view controller that will be shown in controller that is performing segue. And then use it's accessors or other methods to pass needed data inside prepareForSegue:
// In FirstViewController.h
#import "SecondViewController.h"
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"SegueToSecondViewController"]) {
// Get destination view controller and don't forget
// to cast it to the right class
SecondViewController *secondController = [segue destinationViewController];
// Pass data
secondController.dataArray = self.someDataArray;
secondController.name = #"Fancy name";
}
}
When you want data back from second to first, I suggest to use delegate:
// In FirstViewController.h
#import "SecondViewController.h"
#import "SecondViewControllerDelegate.h"
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"SegueToSecondViewController"]) {
SecondViewController *secondController = [segue destinationViewController];
// Declare first view controller as a delegate
secondController.delegate = self;
// Pass data
secondController.dataArray = self.someDataArray;
secondController.name = #"Fancy name";
}
}
// Second controller's delegate method,controller
// ie. used to return data after second view is dismissed
- (void)secondControllerFinishedSomeTask:(NSArray *)someReturnedData {
// Do something with returned data
}
When you want data back from second to first, better way is to use Unwind Segues.