iPhone, slide down help screen - iphone

I like the effect used in many iPhone apps where a semi-transparent help screen slides from the top (or bottom) on top of the current view to show hints or tips. This screen often has a close button as well as "don't show this again" button.
What's the best approach to slide a view on top of the current view for such an effect? Any code example someone can point me towards?
Thanks

You will want to do something like this from the main view controller..
-(void)showHelp
{
HelpViewController *controller = [[HelpViewController alloc]init];
[self presentModalViewController:controller animated:YES];
[controller release];
}
and the done button would either call back to the main controller or dismiss itself using
- (void)dismissModalViewControllerAnimated:(BOOL)animated
Here is the documentation on the UIViewController class. The methods you require can be found there.
The don't show again feature means you will have to save their selection to NSUserDefaults or somewhere else(sqllite,file system). Then you can read that back when your app launches to determine if you should call showHelp.

From your description, and looking at iPhone Human Interface Guidelines, you want UIActionSheet since a modal view isn't semi-transparent by default.
UIActionSheet is also nicer to work with for what you want. You should be able to achieve your goal in a single line.

Related

Multiple XIB's same view

I am wondering if it is possible to have multiple XIB's on the iPhone screen at the same time. So the user can switch from view to view like that.
Mainly what I want to be able to do, is something like the current FaceBook and YouTube app.
Because currently I have lots of views in my application (an all in one calculator) but I would like them to interact more fluidly. (Maybe swipe you finger from the edge of the screen to go to the previously used calculator. Or swipe down from the top to see all of the calculators in a list. Hopefully the thing that swipes down would be another view.
Hopefully you understand what I want to do, and it would be great if someone could point me in the right direction.
Thanks.
All you have to do is instantiate your second xib as a view controller inside your first view controller. From there you can simple add the view property of the second as a subview of the first.. that was kind of a mouthful:
UIViewController *mySecondXibsViewController = [[UIViewController alloc] initWithNibName:#"secondXib" bundle:[NSBundle mainBundle]];
[mySecondXibsViewController.view setFrame:someCGRect];
[self.view addSubview:mySecondXibsViewController.view];
Or if you were to be using storyboards it would look like this:
UIViewController *mySecondXibsViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"someID"];

how to get back to one view to another view in view based application

I did a simple view based application.
what i did is creating view additional to existing view.
means there is one view named main in .xib file additional to that i am creating another view
IBOutlet UIView *view_additional;
In the main view by button click i call the view_additional view.
For the view_additional view i place navigation bar with one bar button named back.
In the back button click event i need to get back to main view.
for that in the button click action i write the fallowing code.
[view_additional removeFromSuperview];
But it is not open main view,shows a white screen.
what the wrong.
how can i get back from additional view to main view.
Thank u in advance.
for the code you used to display view_additional, instead of using self.view = view_additional
try using, on button click
[self addSubview: view_additional];
And once that's done, your code should work just fine the way you want.
When dealing with views, if you change a view, then remove it, as you did in your code, then all that will be left is the main app window. There will be no views on that window. From the look of it, you want to load up a new view, and then remove it once you're done with it. You can do this by adding the new view as a subview instead of totally changing the parent view. Another thing you can do is set an IBOutlet for the original view as well, this way you'll have an outlet for both views, and then instead of removing your additional_view from the superview, you can just switch it back. So the code for the Back Button would just be
self.view = original_view;
on back button click. I hope this isn't too confusing for you. Let me know if you have any questions.
Both methods would work for what you want to do.
I resolve my problem as
instead of [self.view = view_additional];
i use
[self addSubview: view_additional];
To get back to original view in the button click
i use
[view_additional removeFromSuperview];
MahesBabu, that is exactly What I suggested that you do. Only I offered the background info on why you should do it that way.
# MaheshBabu:
This is the common code u can use to go on next view or go on back, Just change button name which u want to press and the view name on which u want to go. For example on back button press u want to go on library view then write this code -
-(IBAction)backButtonPressed:(id) sender
{
libraryView *libraryview=[[libraryView alloc] initWithNibName:nil bundle:nil];
libraryview.modalTransitionStyle=UIModalTransitionStyleCoverVertical;
[self presentModalViewController:libraryview animated:YES];
[libraryview release];
}
Let me know whether ur problem is solved or not.

Multiple View Controllers. Is there a maximum?

I am putting an iPad application together that allows a user to work their way through a virtual tour. They are able to move forward through screens on which some will have buttons to other material such as a video or more info.
If Keynote supported Hyperlinks then it would be well suited but as it doesn't I am trying to recreate the tour within Xcode.
I am a newbie but have spent time researching and have code to display the 'slides' and the capability to move forward and back through them. The slides are no more that an image view with a full screen graphic and buttons for the various options, some slides are simple and have nothing other than back and forward but others will have additional links
However doing it in this simplistic way means I am ending up with a huge number of view controllers and XIB files, currently at 75 which I know must be more than any app should have. However it does work although on occasions when running it on the device and not in the simulator it will bomb out.
My questions are is there a limit to the number of view controllers in one app and will having a large number cause the instability? I'm aware of other ways to handle the views such as having them in arrays and pushing them out a single view controller but this won't give me the flexibility to tailor slides for different content.
I'd welcome any help or advice and I hope have gone about posting this question in the right way (its my first)
Many Thanks
Kieron
The code I am using to manipulate the view is
-(IBAction)goBack {
[self dismissModalViewControllerAnimated:NO];
}
-(IBAction)goForward {
Slide5ViewController *screen = [[Slide5ViewController alloc] initWithNibName:nil bundle:nil];
screen.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:screen animated:YES];
[screen release];
}
Kieron,
Why not have one "slide" view controller and a different image only? Use some sort of data structure to keep information about the buttons, images, and pathways for each slide, and then just keep re-using the same view controller for each slide?
The view controller can then dynamically load each image as it transitions between the currently visible view and the next instantiation of itself... It should be possible using only 1 view controller.
If you're comfortable with using Interface Builder, keep using the XIB files to lay everything out. However, instead of setting each "File's Owner" to a different view controller, set them all to the same one. Then, inside your IBAction methods (when the user pressed a button), use some logic to say "I am on this view right now, and the user pressed this button, so which one should I go to next?"
Then, call a method like loadNewSlide: that might look like this:
- (void) loadNewSlide:(NSInteger)slideNumber
{
// Make a string with the new XIB name
NSString* xibName = [NSString stringWithFormat:#"slide-%d",slideNumber];
// Create the next slide view controller (it doesn't matter if you create a slide view
// controller from within another slide view controller, remember, they are all just
// objects)
SlideViewController *newSlideViewController = [[SlideViewController alloc] initWithNibName:xibName bundle:nil];
// Change the view
UIWindow *theWindow = [self.view superview];
[self.view removeFromSuperview];
[theWindow addSubview:newSlideViewController.view];
// Release, the view stack now should be retaining the view controller instead
[newSlideViewController release];
}
This will work MUCH better than running "modally" with 75 view controllers (as you had previously suggested) because this will only keep 1 slide in memory at a time - whatever you are currently looking at - and then will load the next slide just in time to move to it.
Fist of all, what error is in the log?
Did you properly implemented viewDidUnload method of view controllers? View controllers should be able to unload loaded xib. Also, release data in didReceiveMemoryWarning.
Second, it could be better to use UINavigationController to handle view controllers stack instead of modal view controllers stack. You can hide navigation bar or customize it.

Two Views in 1 view controller

Basically, what I am trying to do is I have my TestViewController and there are 2 views under it, the first view will start with a tool bar and 2 buttons, one for imagepicker and the other one for mail sending, I am already done with that, and after pick the image from the photo library, the second view will be popped out(I want to do some image editing here) with a tool bar and 1 button back to the first view. I am doing something like [self.view addSubview:2ndview], and it works, but when I am trying to use -(IBAction)dismissDrawing:{[2ndview removeFromSuperview] }the program just shut down.
Can anyone help me? Really appreciate your help!
Look at my sample application I did last year. Basically you need a view that will act like a superview, then add views on top of it (if I remember correctly, it's been a while since I did it that way, now I just use multiple xibs).
It sounds like what you're trying to do would be better suited to a modal view.
See Human Interface Guidelines - Modal Views
Instead of adding a subview, try
[self presentModalViewController:secondView animated:YES];
Then in the dismissDrawing you can use
[self dismissModalViewControllerAnimated:YES];

Showing a one-time UIViewController via presentModalViewController upon launch

Greetings! I have a working iPhone app (huzzah!) that uses a MainView.xib containing a fully-stocked UITabBar with several UINavigationController objects and views at-the-ready.
I've now been asked to add a one-time registration view to this mix. This view would appear before the UITabBar at app-launch, get some info from the user, register with a server - or check for an existing registration, then squirrel some data away in the keychain. (If the keychain already shows proof of registration, then we skip showing this particular view.)
The registration and keychain part I've got under control (thank you Erica Sadun for the latter!), but showing that initial one-time view is proving to be trickier than I expected.
I suspect I'm too close to the problem to see what's wrong. I really hope it's pilot error and doesn't require anything too Rube Goldberg!
Here's the scenario:
The app starts by loading MainView.xib, in which lies the aforementioned UITabBar controller, et. al. For the sake of argument, let's say we must show that registration view. Also, we'd like it to have a modal appearance, so it will fly in from the bottom up. Then, when we're done, we can dismiss it, call a delegate (most likely the App Delegate) and tell it to carry on with the original UITabBar.
// Normally, the Tab Bar Controller's view is added to the window ... still do this?
[window addSubview:tabBarController.view];
// We could now set up a VC like so. Mostly harmless. (I know, "mvc" is an unfortunate abbreviation in this case.)
RegistrationVC *mvc = [[RegistrationVC alloc] initWithNibName:#"RegistrationView" bundle:nil];
Note that RegistrationView.xib has a UIView inside, but no nav controller. We want to keep it decoupled so that it can be reused, say, as part of a tab bar item's nav controller (to review your registration info, for instance).
Moving on. We create a nav controller with the intent of presenting things modally:
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:mvc];
We then present our modal VC, using the tab bar controller as the basis, and release the alloc'ed bits.
[tabBarController presentModalViewController:nc animated:YES];
[nc release];
[mvc release];
First observation. Something tells me this is just plain sloppy. You can see the first tab bar item's nav bar and view appear just as the modal view swoops in. Yeccch! Moreover, trying to set the selected VC to nil beforehand has no effect:
tabBarController.selectedViewController = nil;
We really don't want/need to use the tab bar until after the modal VC is done (and we have the delegate to help let us know when that happens).
Why am I even bothering with the Tab Bar? Well, it looks like I need something to hang that modal VC's hat on, and I don't know what else there is to use.
Is this the only way? It just seems to tether the Registration VC and the Tab Bar unnecessarily, and it just smells ... wrong.
Clues welcome/appreciated!
It's hard to answer this without knowing what your Default.png shows. Assuming you're following the HIG and it displays an empty tabBarController, I'd suggest a somewhat complicated layering:
bottom view: tabBarController.view
middle view: UIImageView: Default.png
top view: registration view positioned below the bottom of the screen
On startup, if you need to show the registration view, manually animate it upward, and once the animation is done remove the UIImageView below it. When registration is complete, manually animate the registration view downward to reveal the tabBarController. If on startup you don't need the registration view, just animate the UIImageView to fade away (or just remove it).
OTOH hand, if you're not following the HIG and instead showing some kind of splash screen, things get a bit easier. Layer like this:
bottom view: tabBarController.view
top view: UIImageView: Default.png
If you need to show registration, do presentModalViewController with animated:NO and then fade out the UIImageView. If not, just fade out the UIImageView.
That's a lengthy explanation w/o pictures, hope it makes sense. The salient point is that I'm suggesting adding a UIImageView:Default.png to be the first thing that is seen when the app starts, and use that to guide your transition into registration or tabBarController as appropriate.