In my app I have a list of items in a table view. Tapping on one of them, the app shows details of the item. Details appear and by back button of navigation controller, the app returns to list.
In the detail view I have implemented a method to swipe gesture in order to change the view to the details of the second element of the list and so on. It works.
The method that changes view is:
- (void)oneFingerSwipeLeft:(UITapGestureRecognizer *)recognizer {
int idx=currentIdx;
if (idx ==[todasLasTapas count]-1) { //last object vuelvo al primero
idx= -1;
}
ClassInfo *info =[allInfo objectAtIndex:idx+1];
//VIEW CONTROLLER
MoreInfo *moreInfoController =[[MoreInfo alloc]initWithNibName:#"MoreInfoController" bundle:nil];
//passing the details to view
moreInfoController.id = info.uniqueId;
moreInfoController.name = info.name;
// CHANGE TO NEXT VIEW
moreInfoController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:moreInfoController animated:YES];
}
The problem is that navigation controller disappears when the "second" view appears. My idea is that navigation remains in order to come back to the main table list.
Could someone help me please?
Unfortunately presenting modal view controllers happens outside of the UINavigationController stack. As a result, when you call presentModalViewController, you are bringing a controller onto the screen totally outside of stack of controllers managed by the UINavigationController.
You can preserve most of your implementation, but just switch out the presentation of the modal view controller, by simply adding MoreInfo's view as a subview to the current view.
If you'd like to preserve memory a little more gracefully, just switch between two UIView's (the currently showing view, and the next one to show - which is reused from the last detail view).
Here's an updated version of your code that could do this:
- (void)oneFingerSwipeLeft:(UITapGestureRecognizer *)recognizer {
int idx=currentIdx;
if (idx ==[todasLasTapas count]-1) { //last object vuelvo al primero
idx= -1;
}
ClassInfo *info =[allInfo objectAtIndex:idx+1];
//VIEW CONTROLLER
MoreInfo *moreInfoController =[[MoreInfo alloc]initWithNibName:#"MoreInfoController" bundle:nil];
//passing the details to view
moreInfoController.id = info.uniqueId;
moreInfoController.name = info.name;
[UIView transitionFromView:self.view
toView:moreInfoController.view
duration:2
options:UIViewAnimationOptionTransitionCrossDissolve
completion:^(BOOL finished) {
[self.view removeFromSuperview];
}];
}
Here's a post that shows how to implement a custom animation to dissolve to another UIView:
How to make dissolve animation on changing views on iphone?
Related
No matter what, it seems that my NSScrollViews always appear on top of any other view, even if the other view has been added more recently and should appear on top.
What can I do to get another view (say just a plain NSView) to appear above an NSScrollView?
I finally solved this by setting setWantsLayer to YES (true in this case since I'm using RubyMotion) on the NSScrollView, the NSScrollView's content view and the external view that I want to appear above the NSScrollView.
That solved my problem and allowed other views to appear above the NSScrollView.
So check your xib, and make sure your scrollview is at the topmost of your view hierarchy ("Document Outline"). However, when loaded this doesn't necessarily 100% guarantee that the scrollview will be drawn first. A way to manually force the order you'd like for your views is to programmatically move them around based off tags.
In Interface Builder, in the Attributes Inspector, go to the bottom and find the "View" section. Add a tag to the view, with 0 being the bottom most view you'd like, and going up from there.
Then in your controller, add this method definition & a call to it:
NSComparisonResult compareViews(id firstView, id secondView, void *context) {
NSInteger firstTag = [firstView tag];
NSInteger secondTag = [secondView tag];
if (firstTag == secondTag) {
return NSOrderedSame;
} else {
if (firstTag < secondTag) {
return NSOrderedAscending;
} else {
return NSOrderedDescending;
}
}
}
[self.view sortSubviewsUsingFunction:(NSComparisonResult (*)(id, id, void*))compareViews context:nil];
This will ensure that you have your views in the correct order you'd like
Suppopse there are five view as A,B,C,D,E i am presenting view A to B then B to C using present view controller method. Now i want to dismiss view controller form View C to A directly. How we can do this
One way to do this (and perhaps the simplest) would be to use a UINavigationController and push UIViewControllers onto it.
Then you can simply call: [[self navigationController] popToRootViewControllerAnimated:YES];
Another more complex way to handle this if you really want modal view controllers would be to set up the UIViewControllers with callbacks to register that they should close immediately on next appearance.
-(void)closeImmediately
{
mCloseImmediately = YES;
}
-(void)viewWillAppear:(BOOL)animated
{
if(mCloseImmediately)
{
[self dismissModalViewControllerAnimated:NO];
return;
}
// ... other normal setup code
}
Doing this in viewWillAppear and without animation means that this UIViewController never gets displayed.
I know this is a very popular issue, but i´m having a hard time...so if anyone could help, it would most appreciate:
Im my master tableview (that i have made in storyboard) i have a plus button and every time the user presses that button, a picker view appears...depending on the selection in the picker view, a modal view appears (for this modal view, i have dragged a simple view controller in storyboard and gave it a storyboard id). Each modal view has textfields, and i want to dismiss the keyboard every time the user enters something...to create the modal view i have done this:
CobTableview *produtoCob =[self.storyboard instantiateViewControllerWithIdentifier:#"cobId"];
produtoCob.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:produtoCob animated:YES completion:nil];
produtoCob.view.superview.frame = CGRectMake(0, 0, 350, 512); //do this after presentModalViewController
produtoCob.view.superview.center = self.view.center;
produtoCob.managedObjectContext = self.contextProd;
How can i resolve this?
To everyone that has the same issue...i found out that you need both methods in your modal view controller class :
- (BOOL)disablesAutomaticKeyboardDismissal
return NO
-(BOOL)textFieldShouldReturn:(UITextField *)textField
([textField resignFirstResponder];
return yes
I've got an app where the user selects their country from a picker wheel. An alert comes up and asks them to confirm the change. If they confirm, it takes them to a different view where they can then select from a list of categories to display information...
The list of categories is embedded in a Navigation Controller to facilitate moving from the detailed view "Back" to the category select view.
The entire app is embedded in a Tab Bar Controller.
It works fine (after selecting their country they are taken to the Select Category screen) except that now the Select Categories has lost its connection to the Tab Bar Controller and there is no way to get back to other parts of the app.
Here's my alertView code:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"ok");
//I tried the following but it doesn't do anything
//SelectCategory *switchtocategory = [[SelectCategory alloc] init];
//[self.navigationController pushViewController:switchtocategory animated:YES];
//the following works but loses the tab/navigation bars
[self performSegueWithIdentifier: #"GoToCategory" sender: self];
} else {
NSLog(#"cancel");
}
}
Finding the answer was really about understanding the role of the Tab Bar Controller, how it defaults as the root view controller and then how to work with it to access the various view controllers, instead of trying to segue. Reading the Apple documentation helped with this but the code turned out to be very easy:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
NSLog(#"ok");
//the following transitions to tab #3 when the alertView is touched/clicked/dismissed
[self.tabBarController setSelectedIndex:2];
} else {
NSLog(#"cancel");
}
}
I need a custom leftBarButtonItem on my navigation bar because I need to perform a function in the view controller when the view is popped. I would like to have the back button have the correct title (of the view controller below). So two questions:
1) Can I get the title of the standard backBarButton item somehow, so that I can manually set my custom button's title?
or
2) Is there another hook/event that I can use that is only called when the user pops the view?
Re 2: I found one solution using:
NSArray *viewControllerArray = [self.navigationController viewControllers];
int parentViewControllerIndex = [viewControllerArray count] - 2;
But this array is (null) for me.
PS I'm using Three20.
There's a UIViewController function which gets triggered when the view controller disappears from the screen:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
.....
}