I am using SWRevealViewController for navigation drawer in iOS.I have one main screen which is shown by default when app launches.I have also other screens like Settings,Help,About. So when user switch between screens then state of 1st view controller is reset.I want to persist it's state lie if was showing some data in screen then it should not get removed.
I am using below code to switch between screens.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
if(indexPath.row==0)
{
[self performSegueWithIdentifier:#"home" sender:cell];
[cell setSelected:YES];
}
else if(indexPath.row==1)
{
[self performSegueWithIdentifier:#"settings" sender:cell];
}
else if(indexPath.row==2)
{
[self performSegueWithIdentifier:#"help" sender:cell];
}
else if(indexPath.row==3)
{
[self performSegueWithIdentifier:#“about” sender:cell];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Segue");
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[titles objectAtIndex:indexPath.row] capitalizedString];
if([segue.identifier isEqualToString:#"settings"])
{
self.revealViewController.navigationItem.title = #"Settings";
}
else if([segue.identifier isEqualToString:#"help"])
{
self.revealViewController.navigationItem.title = #"help";
}
else if([segue.identifier isEqualToString:#"about"])
{
self.revealViewController.navigationItem.title = #"about";
}
if([segue isKindOfClass:[SWRevealViewControllerSegue class]])
{
SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: #[dvc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
};
}
}
One solution I see that to keep the viewController in the navigation stack so that the viewController not get destroyed it remains in the stack when user go to "home" then it is relaunched from navigation stack instead of initializing the view controller again.
For example for HelpVC , you store a property of it in your side mennu view controller:
#property (nonatomic, strong) HelpViewContoller* helpVC;
Than in row selection instead of calling your segue, you instantiate the view controller, but before that you check if it is instantiated already you use it:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
if(indexPath.row==0) {
if (helpVC == nil) {
helpVC = [self.storyboard instantiateViewControllerWithIdentifier:#"helpVCidentifier"];
[self changeFrontVCto:helpVC];
}
}
}
-(void) changeFrontVCto:(UIViewController*)vc {
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: #[vc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
}
Related
I went from one ViewController to another using Segue in my second viewController has an UITableView. now, I want to push from second ViewController's didSelected method to another viewController.
code use to Segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
SearchVC *svc = segue.destinationViewController;
self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
}
under button action:
-(void) searchButtonClicked:(id)sender {
[self performSegueWithIdentifier:#"search" sender:nil];
}
And the main problem arise here, can't navigate using below code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PackageListVC *pdvc = (PackageListVC *)[self.storyboard instantiateViewControllerWithIdentifier:#"PackageListVC"];
pdvc.strServiceProviderId = [[[arrSearch objectAtIndex:indexPath.row] objectForKey:#"ServiceProviderId"] stringValue];
pdvc.strCategoryId = [[[arrSearch objectAtIndex:indexPath.row] objectForKey:#"CategoryId"] stringValue];
pdvc.strSubCategoryId = [[[arrSearch objectAtIndex:indexPath.row] objectForKey:#"SubCategoryId"] stringValue];
pdvc.strTitle = [[arrSearch objectAtIndex:indexPath.row] objectForKey:#"CompanyName"];
[self.navigationController pushViewController:pdvc animated:YES];
}
You do it in the prepareForSegue method.
where you declare svc (SearchVC *svc = segue.destinationViewController;) you can say something like:
svc.variable = 1;
I'm working on an iPad app where I use UISplitViewController. I also use DetailViewController in which to display some information from XML, but the information is not displayed in DetailViewController but in MaterViewController. I really do not know how to fix it. Can you please help. Thank you
There is code:
-(void) showDetailsForIndexPath:(NSIndexPath*)indexPath
{
[self.searchBar resignFirstResponder];
DetailViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailsViewController"];
Slova* slova;
if(isFiltered)
{
slova = [filteredTableData objectAtIndex:indexPath.row];
}
else
{
slova = [self.slovoArray objectAtIndex:indexPath.row];
}
vc.slovoItem = slova;
[self.navigationController pushViewController:vc animated:true];
}
The reason is that you're pushing the new UIViewController onto the stack for self, which is presumably the MasterViewController. Instead, create a new project using Apple's Master-Detail Application and you'll see how they do it.
Caveat: they use Storyboards, but it is very possible to do this all in code.
In Apple's example, both the MasterViewController and the DetailViewController are visible from the start (in landscape).
Look how Apple's example sets detailItem (slovoItem?) for DetailViewController:
#pragma mark - Segues
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = self.objects[indexPath.row];
DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController];
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
}
}
So, you'll have DetailViewController already visible and you'll just update its detailItem property.
Therefore, the following code exists in DetailViewController:
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem {
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView {
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
The following code is in my menuViewController.m. Now I want to go to another view when touch on a specific cell. What should I do to go to contactViewController?(I am using storyboard)
storyboard image:
https://drive.google.com/file/d/0BwOYR2GMJ7l8U1lYYVFVTWVkOG8/edit?usp=sharing
code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
NSString *CellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row==2)
{
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[menuItems objectAtIndex:indexPath.row] capitalizedString];
if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: #[dvc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
};
}
I want to go to another view when touch on a specific cell.
For this, I'd do it this way:
Step 1:
Drag from TableViewController to ContactViewController:
Step 2:
Select segue and specify the Segue Identifier (Show attributes Inspector tab in the right side bar)
I have named the Segue Identifier as SegueTestID
I chose Push as my style but it seems you might need Modal
And the corresponding code (in your MenuViewController.m) should be something like:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 2) {
[self performSegueWithIdentifier:#"SegueTestID" sender:self];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//following lines needed only if you need to send some detail across to ContactViewController
if ([segue.identifier isEqualToString:#"SegueTestID"]) {
ContactViewController *destinationViewController = segue.destinationViewController;
destinationViewController.strTest = #"Check";
//where strTest is a variable in ContactViewController. i.e:
//"#property (nonatomic, strong) NSString *strTest;"
//declared in `ContactViewController.h`
}
//...
}
PS: It seems you have alot in your -prepareForSegue: already.
Obviously... you'll need to hook things up properly.
In Storyboard , Do this ( In your case its contactviewcontroller ) give the name identifier name to contactViewController whatever you want as shown in image for showRecipeDetail
and you can go to the contactviewcontroller
and then
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
destViewController.recipe = [recipes objectAtIndex:indexPath.row];
}
}
In above method it shows how to pass the data from current viewcontroller to destviewcontroller
where We simply set the property (i.e. recipeName) in the RecipeDetailViewController to pass the recipe name. Obviously, you can add other properties in the detail view controller to pass other recipe-related values. ( In your case it will be data you want to pass to contactviewcontroller)
When a segue is triggered, before the visual transition occurs, the storyboard runtime invokes prepareForSegue:sender: method of the current view controller. By implementing this method, we can pass any needed data to the view controller that is about to be displayed. Here, we’ll pass the selected recipe object to the detail view controller.
So, Im developing an app with a slide-out menu, where I have used the tutorial and project-files from AppCoda (http://www.appcoda.com/ios-programming-sidebar-navigation-menu/).
This slide-out menu is created by JSON from a database, and is working as it should, however, when I press one of the cells, it won't load the new ViewController.
I have tried using this code, to make it work:
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Rules *currentRule = [rulesArray objectAtIndex:indexPath.row];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [currentRule.ruleTitle capitalizedString];
if ([segue.identifier isEqualToString:#"showRule"]) {
PhotoViewController *pvc = (PhotoViewController*)segue.destinationViewController;
pvc.people = currentRule.rulePeople;
pvc.content = currentRule.ruleText;
[self.navigationController pushViewController:pvc animated:YES];
}
if ([segue isKindOfClass: [SWRevealViewControllerSegue class]]) {
SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: #[dvc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
};
} }
The segue, combining the two views is attached to the TableView (the menu) and the PhotoView. Can anyone see what I'm doing wrong?
I'm using SWRevealViewController to build a side bar menu.
I have that method to select the right controller when selecting an element from the menu(UITableView). The segue identifiers/names are configured in the storyboard.
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
NSLog(#"Tapped");
// Set the title of navigation bar by using the menu items
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
destViewController.title = [[_menuItems objectAtIndex:indexPath.row] capitalizedString];
// Set the photo if it navigates to the PhotoView
if ([segue.identifier isEqualToString:#"showToday"]) {
[segue destinationViewController];
}
if ([segue.identifier isEqualToString:#"showCountries"]) {
[segue destinationViewController];
}
if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: #[dvc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
};
}
}
But nothing happens when selecting an item from the side bar menu.What could be the problem?Thank you for helping.
My fault, was selecting "Accessory action" instead of "Selection Segue" "reveal view controller".