Two Views in 1 view controller - iphone

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];

Related

iPhone Structure ViewController

I am designing an iPhone application with a home page. This page has multiple buttons (6) that go to different things.
2 buttons are a simple view that just have some information and go back to the home screen. The next button opens up an email and I believe that will just be one view, so not a whole lot different than the other two.
Here is where it gets complicated. One button will take a picture, and another will select one from the library. Once that is done it will edit it and create an object that I will create. That object will be stored in an array, which will be opened by the last button one the home page and a UITableViewController will control that.
My first question is should I use a navigation based view controller or just a view controller that I can create myself? Or should I use something that I don't even know about?
Please Help!!! And if you help a sincere thank you!
EDIT:
Well i tried it my own way first and the only issue i'm having is this code
- (void) displayView:(int)intNewView {
NSLog(#"%i", intNewView);
[home.view removeFromSuperview];
Instructions *i = [[Instructions alloc]init];
instructions = i;
[self.view insertSubview:instructions.view atIndex:0];
}
It is in my SwitchClass, which controls the Main Window's view. I know it is working there because when it first runs the switch class directs it to the home screen. I know the method is being called because the console is displaying the NSLog thing, but it just won't switch.
Aside from the fact that you have 6 buttons, I would try and use a UITabBarController for what you are trying to do; it would seem more natural to me (but you should find a way to reduce you 6 button to 5, otherwise they will not be displayed all at once).
Otherwise, a UINavigationController seems fine to me. For each button you push a new controller to deal with that button functionality, then you pop back. It should work easily.
EDIT:
have you tried with?
[self.view addSubview:instructions.view];
Your first question Yes you should use navigation based controller ... so when you press any button will open the other view controller with animation.. also Navigation Based Controller keep track of the parent controller if you have any created objects will be retained in the parent view controller that is the root of the Navigation.
here is the steps that you should use.
1-Create Navigation controller in the main application delegate and make it's root is the view controller.
2-when you push the view controller that have 6 buttons .
3- you can check this link for get photo album also if you have changed the source type to camera then you can get the image...
Photo Libaray
4- once you get the image you can add it to NSMutableArray that exist on the NavigationViewController root in your case will be the view which have the 6 buttons.
5-sice every time you want to view the array which contain the photos you will initialize the data source of the uitableviewcontroller with the array that you save photos on.
Thanks
I think the problem is coming from one of two places:
As I understand it, these are all different View Controllers, correct? And they have their own xib files? If that is true, then calling:
Instructions *i = [[Instructions alloc]init];
is insufficient. You need to use
Instructions *i = [[Instructions alloc] initWithNibNamed:#"Instructions"];
in order to include that view that you have already constructed in the interface builder.
The other thing I see potentially going wrong is that you are inserting all the views at the same index. Think of the index as a layer in photoshop. If you want the new view to be visible overtop of the last one, then it needs to be a higher index. This is handled automatically if you use addSubview: instead of insertSubview: atIndex:

Loading an external view controller, from a button click on another view controller

Im officially getting annoyed with objective-c and xcode now. Programming in PHP and Java is so much easier haha.
Anyway I could do with some help.
I have created a tab bar application with three tab items for the iPhone, on one of the items it loads a nib named mapView, this contains a button that I want to use to load up another nib named OverlayViewController.
Ive been following this tutorial this tutorial
to create a camera overlay. I understand how it works, but I don't understand how to run the view controller from a button or direct from the tab bar. I can only get the overlay to work if I load it like in the example on application launch in the app delegate. If I try and load it from the tab bar item I just get a grey screen, looks like the blank view controller is loaded and the code hasnt been run to show the overlay.
If anyone can suggest how I would go about loading the overlay from the button click, or even direct from the tab bar item I would be really grateful.
Thanks Alex
p.s. Heres the link to the project if you wish to view the files
#AlexApps I took a look through your project and have several pieces of feedback.
I think before you get too into trying to get the OverlayViewController working you should back up a bit and give some of the Apple docs a read, especially the View Controller Programming Guide. The Apple docs are for the most part well written and should help you gain a better understanding of views and view controllers than what is evident in your code.
Another suggestion is to grab some of the freely available source code from a book such as Beginning iPhone Programming which has a good example of how to lay out a tabBarController based app. I am sure there are other good samples out there that will show you how to organize your views and view controllers to load them into the different tabs.
I think that if you follow this advice that by the time you have restructured your app by what you learn you will have less problem doing what you are trying to do.
BTW, you may want to consider using a NavigationViewController for what you are trying to do with loading the OverlayViewController with a button press but take a few hours, slow down and do some focused reading. It will make a world of difference. Then if you have more specific questions, Stack Overflow (and Google) are your friends.
One last tip, you do not need to put IBOutlet in your instance variables AND in your properties, just one or the other, and really, you don't even need the instance variables at all anymore. I usually just use properties for everything.
I have done it with storyboard and the solution is to create a segue between the tab bar view controller and the view controller you want to load, then you have to put an identifier to that segue. Finally, in the method called when the button is pressed you have to put this:
[self performSegueWithIdentifier:#"segueId" sender:sender];
I have done it right now and it works perfect!
First import uiviewcontroller class in frist page like below:
#import "page2viewcontroller.h"
on button click event code below:
page2viewcontroller *page2 =[page2viewcontroller alloc] ;
[self presentModalViewController:page2 animated:NO];
[page2 release];
after back page2viewcontroller to page1viewcontroller same as like below:
#import "page1viewcontroller.h"
on backbutton click event code below:
page1viewcontroller *page1 =[page2viewcontroller alloc] ;
[self presentModalViewController:page1 animated:NO];
[page1 release];
That's all....!

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.

Weird Scrolling Issue Using UITableView

I am a working UINavigationController pushing two different UITableViews on and off the stack. All of my functionality is working correctly except scrolling. When either table is scrolled above the top row, or below the bottom row, it stays there exposing the margin above/below the table. I am looking for the table to "bounce" back so that only the table is visible and not the white space area beyond - just like any other iPhone app.
One of my UITableViews is being loaded by NIB and the other is being created programatically - both of which have the exact same result. I have tried all the bounce and scrolling settings in the Nib, but nothing seems to work.
Can someone tell me what I am doing wrong? Please let me know if I can be more specific in detailing my problem.
Thanks,
-Scott
I wanted to add a bit more information since I am still unable to figure out this problem. I should point out that the app I am trying to add this NavigationController to is NOT the main view. I have a SettingsViewController that uses a Nib to get loaded. Within that controller, I am wanting to create a new navigation based set of views. So From inside my SettingsViewController, if the user taps a button, I...
Within my button selector:
TextListViewController *controller = [[TextListViewController alloc] initWithStyle:UITableViewStylePlain];
controller.title = #"Test Table View";
navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:navController animated:YES];
[controller release];
The above code works perfectly in every way except scrolling. I am able to process all the delegate methods and push new controllers onto the stack. The ONLY issue I am having is that the root controller (and every other controller pushed) will not scroll correctly.
In every case, it allows me to scroll past the top and bottom of the table and does not snap back like it should. It also does not have a free-wheel feel to it when you flick scroll. Instead, it stops as soon as you remove your finger no matter how fast you scrolled. Very odd.
I have tried creating another project using the Navigation template - and of course it works fine - but the template assumes the NavigationController's view is attached all the time - which is not my case. I am creating all of this on the fly within a standard ViewController.
Thanks for your help Kevin, but I am still looking for some help here.
Thanks,
Well, I fixed the issue and it had nothing to do with how I was adding the UITableView to the UINavigationController or in how I was instantiating the view. It turns out it was completely unrelated to any of that.
I am using a tight while loop to process my game loop. I needed a way to process OS messages in the loop to keep touches and other events from being blocked. Here is what I was using in the middle of my loop:
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, TRUE) == kCFRunLoopRunHandledSource);
Up until this scrolling problem, I had no problems with this implementation at all. For whatever reason, this is breaking the scrolling functionality with UITableView.
I changed my game loop so the above code is not needed and everything started working.
Thanks...
Your UITableView is a UIScrollView, whose property bounces is the key. Here's the reference. By default it is YES, though. Did you check this one?
Your question and comments seem to suggest that you are attaching a UITableView to your UINavigationController in some way other than by pushing a UITableViewController. If you're not doing it that way, you really should.
In general, if you can push a child view controller onto a UINavigationController, then you can also use the child view controller by itself just to test it out. Try making your UITableViewController's view the root view of your window, and see if that does what you expect. That way you can isolate the problem to either the table view part or the navigation part.
I've been having the same issue as you which as you state above was related to the way you were calling the runloop:
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, TRUE) == kCFRunLoopRunHandledSource);
Seems like DefaultMode is the wrong thing to be waiting on, I changed my code to wait on UITrackingRunLoopMode and the TableView worked correctly. In my case I used:
[[NSRunLoop currentRunLoop] runMode:UITrackingRunLoopMode beforeDate:[NSDate distantFuture]];
And everything worked correctly.

iPhone, slide down help screen

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.