Sequential (not hierarchical) navigation in iPhone - iphone

I'm getting frustrated at this.
I want to create an iPhone application to show a list of events, one day for each 'screen'. I want a bar at the top with 'next' and 'prev' buttons that allow me to go to tomorrow or yesterday.
It is not a UINavigationController style navigation, because navigation is not hierarchical. Therefore I don't think I should use the pushViewController: method, as many examples and tutorials suggest.
I think that the appdelegate class should remove the current view and create a new viewcontroller and view and add it to the window. However I can't manage to get it working. Also I would like nice transitions.
Can someone point to a code sample that I can look at?
Thank you.
P.D. My question is similar to this one but there is no useful answer.

I wouldn't get hung up on the view controller so much. The view controller/view duality can sometimes get in the way of building custom interfaces.
What you need is a UIToolbar with two buttons, and a sorted array of UIView objects configured appropriately for your entities.
Then when the buttons are clicked, simple [UIVIew animations] should get the job done.
I'm not going to write the code for you. Any casual analysis of the build in UIView animation components will point you on your way.
The only real thing I can tell you is that, having built sophisticated interfaces for the iPhone, the biggest learning curve is knowing when and when not to use UIViewController as opposed to UIView. This is tricky because most of the standard apple components use Controller.

Now it works. Just some details were missing. I'll leave the answer here so that other people can comment on it or use it.
In the AppDelegate class I added this method:
-(void) navigateToDay:(NSDate*) newDay fromDay:(NSDate*) currentDay
{
UIViewAnimationTransition transition = ([newDay compare:currentDay]<0)? UIViewAnimationTransitionCurlDown :
UIViewAnimationTransitionCurlUp;
SequentialNavigationViewController* newController = [[SequentialNavigationViewController alloc] initWithNibName:#"SequentialNavigationViewController" bundle:nil];
newController.app = self;
newController.currentDay = newDay;
[newController.view setFrame:[[UIScreen mainScreen] applicationFrame]];
[UIView beginAnimations:#"transition" context:NULL];
[UIView setAnimationDuration:0.50];
[UIView setAnimationTransition:transition forView:self.window cache:YES];
[window addSubview:newController.view];
[self.viewController.view removeFromSuperview];
[UIView commitAnimations];
self.viewController = newController;
[newController release];
}
And I call this method from the SequentialNavigationViewController prevButtonClicked and nextButtonClicked methods.
Not so hard after all!

Related

iOS views animation

I am trying to create an animation for switching views on iOS devices.
I have create an application with three views and I have some navigation buttons.
The way I use to switch views is this:
-(IBAction) loadThirdView:(id)sender {
[self clearView];
self.thirdViewController.view.frame = CGRectMake(0, 208, 160, 208);
[self.view insertSubview:thirdViewController.view atIndex:0];
}
As you can see this is the action that takes place once I press the button. What I would like is the new view to appear in an animated way.
Specifically I want it to start from the left hand side of the screen and slide to the right. I do not want it just to appear.
Is this possible? how can I do it?
Oh no! Ah, no! Please do not display UIViewControllers this way.
Present your UIViewController this way:
[self presentModalViewController:self.thirdViewController animated:YES]
Before presenting it, you can change the modalTransitionStyle property of the view controller to suit your needs.
If using a UINavigationController, use instead:
[yourNavController pushModalViewController:self.thirdViewController animated:YES]
This is a nice little article (if not a little too harsh): Abusing UIViewControllers
To animate it the way you specifically would like (as the UINavigationController style is sliding in from the right), you might want to use something like what is proposed in this SO question: iPhone Pushing View Controller in a left direction
You can try
[UIView transitionFromView:currView toView:nextView duration:0.5f options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
if you want different type of animation. There're lots AnimationsOptions you can choose, just set the options:.
Sample Code :
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.6];
yourImageVieew.alpha=0.9;//insert here what you want
[UIView commitAnimations];

UIView being pushed up (apparently)inexplicably

I have a problem with UIViews to which I really don't know how to proceed.
It will be futile to describe my problem so here are the screenshots of before and after.
Somehow the UIView gets the layout that was defined in interfacebuilder AFTER an image is chosen. Before an image is chosen it doesn't obey to its defined layout for some reason.
Before using imagePicker for picking an image:..........................After Picking image:
|
So yeah that is basically the problem. The black squares are other images and you can tell by that how it should and how it shouldn't, one of the images is being cut (normally behind the "No SIM" label.) I just put them to hide the real images on the screenshots.
So maybe is something in relation to two things I do here.
I resize the image chosen to 320-480 and put it on a smaller UIImageView before uploading it to a server.
If the user is writing on a textField the entire view is animated up, so the keyboard won't hide the textFields.
UPDATE:
I noticed this happens on a UIView that does nothing related to resizing images or textFields. This is happening too on a UIView I have where there are only 3 buttons and 2 labels. Only 5 elements. The 3 buttons are in custom mode with images. So 3 image~Buttons and 2 labels....
Thank you for your help and suggestions fellow Stackoverflowers!!! (Stackoverflowerers?)
I really have no idea on how to proceed here, though I've been playing around transforming the UIView at the viewDidLoad to no avail.
UPDATE 2:
I started to think that maybe there is something wrong with the code I use to make the transition from view to view and has nothing to do with the elements that are contained in it. Since it is happening in all my views EXCEPT the first view. So here is the code I use for the transition of views:
- (void) flipToUploadView {
UploadViewController *aUploadView = [[UploadViewController alloc] initWithNibName:#"UploadView" bundle:nil];
[self setUploadViewController:aUploadView];
[aUploadView release];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES];
[uploadViewController viewWillAppear:YES];
[viewController viewWillDisappear:YES];
[viewController.view removeFromSuperview];
[self.window addSubview:[uploadViewController view]];
[viewController viewDidDisappear:YES];
[uploadViewController viewDidAppear:YES];
[UIView commitAnimations];
}
Sorry don't have enough reputation to comment, but
have both views the same nib?
if not, is it possible that you just forgot to simulate the status bar in InterfaceBuilder for the few which is drawn uncorrect? and thats why the positions are different?
And i think what Tommy means is that normally you use the ModalViewcontroller to change views
[self presentModalViewController:uploadViewController animated:YES];
than all the function calls (willappear,didappear,willdissappear...) are called automatically
but i think this is not the source of the wrong displaying

iPhone CATransition adds a fade to the start and end of any animation?

So I am just beginning recently developing some simple apps for the iphone. I will say that I am fairly sure I don't have a strong understanding of programming for multiple views yet, but I am trying to learn as I go.
I have a program that started as a plain window based application so i could hand write everything in hopes of learning more about what i am doing. I have a single view controller that acts to load and release views as requested from each of the other view controllers. No elements persist from one view to the other.
I have that working fine currently, but I wanted to add animations to the view changing. A simple push animation was my goal. One view pushes out as the new view pushes in.
Looking into CATransitions and trying that, I have a working version (currently for pushing top/bottom)
[thisView.view removeFromSuperview];
[thisView release];
thisView = [[MenuViewController alloc] initWithNibName:#"MenuView" bundle:nil];
[self.view addSubview:thisView.view];
CATransition *animation = [CATransition animation];
[animation setDuration:6.3];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromTop];
[animation setRemovedOnCompletion:YES];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[[self.view layer] addAnimation:animation forKey:nil];
as far as I can tell this is pretty standard code for using CATransition and it works to do what I need, one view gets pushed up as the other view comes in. However my problem is that there seems to be a fade that happens to each view as they come in or go out respectively.
As such - in this example; as the menu pushes up from the bottom, it will very slowly fade in from white, and as the previous view leaves the screen it will slowly fade to white.
Note that the duration is set to 6 so that the fading is dramatic.
Is there a way to remove the fading here so that each view remains solid on the way in and the way out? Or have I missed the mark completely in this route that I am taking?
I appreciate any help. Apologies I have been long winded.
I have never been able to find a solution to this problem, but I can offer a reasonable workaround. What's happening is it isn't fading to white, but fading to transparent, and the window background (or whatever view is behind) is white. There are a couple ways to get around this:
Change the window background color. If both views you're fading between have the same solid background color, then this will look pretty good.
Don't render a background in each view ("MenuView," for example), but rather have a shared background view that's under those views at all times.
Note that this will not work in all circumstances -- grouped UITableViews, for example, are always completely opaque.
(As I side note, I assume that you aren't build a navigation-based application, in which case all the animation should be handled automatically.)
You also might want to consider the looking into the UIView method setAnimationTransition:forView:cache: if you haven't already as another way to transition between views (although it cannot do a sliding animation, if you are set on that).
I solved this by enclosing the view to which I have applied the effect into a superview and by setting the superview property "clip subviews". now the fade is "clipped" by the superview.
I was able to get the views to transition without fading at the beginning and end by using UIView animation. NOTE: In the code below, I have a UINavigationController and a UITabBarController inside a main UIView. The main UIVIew (containerView) is what I added as a subView to the Application window. The other two are subviews of the containerView.
UITabBarController *tabBarController = [(AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate] tabBarController];
UIView *containerView = [(AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate] containerView];
UINavigationController *accountsNavigationController = [(AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate] accountsNavigationController];
CGRect accountsNavigationControllerEndFrame = containerView.frame;
CGRect tabBarControllerEndFrame = CGRectMake(containerView.frame.size.width, containerView.frame.origin.y, containerView.frame.size.width, containerView.frame.size.height);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
tabBarController.view.frame = tabBarControllerEndFrame;
accountsNavigationController.view.frame = accountsNavigationControllerEndFrame;
[UIView commitAnimations];

provide transitions between view controllers

i am new to iphone application development.
I have a mainmenu view controller, which has a login button.
once i click the login button i display the next login view controller by calling this
LoginController *lc2=[[LoginController alloc] initWithNibName:#"LoginController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:lc2];
[self presentModalViewController:navigationController animated:YES];
But this view appears to come from the right side of the screen,i want to provide the effects like, curl or flip,when i navigate from one view controller to another.
Please help me with the code to provide this effect
Check the Metronome example from Apple's SDK. Its a bit too much code for posting it right here, hence I would like to point you to that example.
The basic idea is using a parent view-controller that handles the transitions between two or more child view-controllers. That involves setting up a protocol for smoothly allowing the child-view-controllers to inform the root-view-controller about transitions to do. Bit vague, I know - so please jump into the example code.
Perhaps something like this, separating the animation code from the modal view controller's presentation code:
LoginController *lc2=[[LoginController alloc] initWithNibName:#"LoginController" bundle:nil];
UINavigationController *navigationController =
[[UINavigationController alloc]initWithRootViewController:lc2];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView:navigationController.view cache:YES];
[self presentModalViewController:navigationController animated: NO];
[UIView commitAnimations];
I quite agree with luvieere, except I think that the view specified in
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView:navigationController.view cache:YES];
must be the container view, in wich a subview will be added or removed, and I'm not sure if navigationController.view is the container view. I would try with different combinations, including self.view, self.view.superview (that depends of the behavior of "presentModalViewController").

How to change XIB in a tab bar application?

My iPhone app is tab bar-based, but I would like to fire an action which switches out the tab bar controller view completely and replaces everything in the window with a view from a different XIB file. I would guess this has to be done in the application delegate (since this is the "chief" class), but I don't know the right way to go from there. Does anyone know how to do what I am trying to do?
Thanks in advance!
Your tab view controller could have it's action method, such as -(IBAction)onChangeView and that method calls a method on the [[UIApplication sharedApplicaton] delegate], such as -(void)toggleScreen.
-(IBAction)onChangeView:(id)sender
{
MyAppDelegate *delegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate toggleScreen];
}
Then in your app delegate method do something like this:
-(void)toggleScreen
{
[[[window subviews] objectAtIndex:0] removeFromSuperview];
[window addSubview:otherView];
}
It may be different if you need transitions, however.
You don't really have to go all the way to the app delegate. You can easily remove your existing views and controllers and add new views. It really does depend on what you are doing. You could, for example, temporarily put aside the existing view structure and go with something totally different, and get back to the original scheme if you want (I'm not sure of the user experience though).
In my apps, I usually have a root view controller or I use my main window to add views to and remove views from. Some views will add other views to themselves or transition another view onto the rootview or main window. Some views close themselves to reveal the view below. The options are limitless, and depend on your needs and architecture.
Thanks guys! Nick, that's just the code I needed. In case anyone finds this handy, here's the code I used to add animation to switch the view. Just put this in a method in the app delegate:
AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:#"AnotherView" bundle:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.window cache:YES];
[[[window subviews] objectAtIndex:0] removeFromSuperview];
[window addSubview:[anotherViewController view]];
[UIView commitAnimations];