I am developing an iPhone application for a university project and I'm new to iPhone development. I have looked through Apple's MapCallouts code but it doesn't seem feasible to implement it.
So far my code displays a map, drops annotations, displays the title and it displays the right call out button. But this is where I encounter problems.
When I press on the callout button, it displays a blank view controller but it should display a different image for every callout that's tapped and this isn't happening so far.
I have added my code below:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
//NSUInteger tag = ((UIButton *)control).tag;
if (self.detailController==nil)
{
DetailViewController* detailViewController = [[DetailViewController alloc] init];
[self.navigationController pushViewController:detailViewController animated:YES];
}
// self.detailController.tag =1; //to identify image required
// self.detailController.tag = tag;
[self.navigationController pushViewController:detailController animated:YES];
}
If you are using storyboard, then you should already have a view controller. I'm assuming your code is in the class that your view controller is an instance of.
The easiest (least coding required) way to present an image is to:
Drag a view controller into the storyboard
Drag a UIImageView into the view controller
Select the image you want to show up in the properties editor of the UIImageview
Control-drag from the button in your main view controller to the view controller containing the image
This should have created a segue. Select the segue and select "modal" from the style menu
You can do this for each image you want, but it is messy. Consider also subclassing the image controller and programmatically defining the image you want to show up. You may need to do this anyway if you want to dismiss the image with the dismiss modal view controller method. The alternative would be adding another segue that points backward.
Related
In my iPhone app I am trying to have the allusion of having a single static navigation bar, so the title and buttons don't ever swipe across when switching views.
I can't think a way of doing it (simply at least), so do you have any suggestions? I need to have a static title and buttons up in the nav bar space (even if I don't use the UINavigationBar, but make something custom) so that when I do something such as push a view controller, when it swipes across my nav bar doesn't move and the buttons change function for the new view.
Edit
Ok, I have thought of a possible method. Each of my views have a secondary view in which gold the view contents, except the nav bar objects. Can I override the pop and push methods to just animate this subview on and off screen?
Just do a push as normal but set it to not animate.
i.e.
[self.navigationController pushViewController:newViewController animated:NO];
Then when you want to go back...
[self.navigationController popViewControllerAnimated:NO];
Then you can have two navigation bars but it will look like it's the same bar as it isn't animating.
EDIT TO ALSO ANIMATE IN THE VIEW AND KEEP THE NAV BAR
I'm not sure of the whole flow of the app but if you want to keep the nav bar and swipe the new UI in then you could create a scroll view (with paging) and put the views of each VC on different frames of the scroll view or something.
Why do you want to keep the nav bar still anyway? There is nothing wrong with animating the nav bar and keeping the same buttons etc on it.
Having said that, if you are using different VCs then the nav bar should change anyway to show the details (i.e. title) of the VC you are currently looking at.
ANOTHER MORE RADICAL APPROACH
OK, thinking laterally now :D
How about, you use the not animated push and pop (as above) but instead of just displaying the UI you can animate it in from the relevant side. (A singleton or a VC subclass which you then subclass for your UI could do this for you across all view controllers).
The next problem is that it will look like the UI has gone instantly blank before animating in the new UI so you need to animate out the old UI. This means both UIs (the old and the new) have to be on the screen at the same time.
You can get round this by converting the entire view of the old UI into an image (not hard to do will find a link) and then passing this image into the new VC. The new VC will then instantly display this image and animate it out of the screen at the same time as animating its own UI onto the screen.
Really not as hard to do as it sounds. Especially if you subclass UIViewController ad give it a function animateUI and a property oldUIImage and direction. Then you can override viewWillAppear in this class to do the animation for you. Then the only thing you have to do is give each VC an image and a direction when you push/pop to it.
This is just giving the illusion of what you're after and means you can still keep a fairly simple object model and flow of the app.
...or something.
Just a riff on #Fogmeister's good idea...
In the presenting view controller, get self.view's image by implementing the suggestion here. Then, when it's time to present...
UIImage *image = [self makeImage]; // what it was called in the other post, consider a better name
MyViewController *newVC = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
newVC.presentationImage = image;
[self.navigationController pushViewController:newVC animated:NO];
In MyViewController, give it a UIImage property called presentationImage, then ...
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.presentationImage];
imageView.frame = self.view.bounds;
imageView.tag = 128;
[self.view addSubview:imageView];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIImageView *imageView = (UIImageView *)[self.view viewWithTag:128];
[UIView animateWithDuration:0.5 animations:^{
imageView.frame = CGRectOffset(imageView.frame, -self.frame.size.width, 0);
}];
}
FYI - I didn't test or even compile this. Just liked the idea and decided to stretch my fingers.
To do this in a "clean" way, you'd need to abandon UINavigationController and write a custom container controller that does not push new navigation items onto it's navigation bar when pushing a new view controller (or allows you to push the navigation item in a non-animated fashion while animating the push of the view controllers views).
However doing this will take some time. If you decide to do this, i recommend the WWDC Session on UIViewController containment.
Another alternative that springs to my mind is to (by subclassing or method swizzling) alter the behaviour of UINavigationController to push the navigation items non-animated while animating the viewcontroller-push.
I have in no way tested this, but overriding push (and pop respectively) in a subclass like this might work:
- (void)pushViewController:(UIViewController *)vc animated:(BOOL)animated {
[super pushViewController:vc animated:animated];
[self.navigationBar setItems:self.navigationBar.items animated:NO];
}
If this method doesn't work, it might be worth inspection what animations are going on inside the nav bar directly after the call to pushViewController:animated:. Maybe you can cancel some animations to go to the final state directly.
My question is quite simple but no way to find a simple exemple on internet.
I have a main view controller with buttons and i'd like to display an UIView created with IB when i click on a button, so for exemple:
-ViewController (.h/.m/.xib) is my main interface with a menu button
-MenuView (.h/.m/.xib) is my view that i would like to be displayed as a pop up window over my uiviewcontroller.
So how is it possible to control my MenuView from my viewController ? Is it possible to create it with IB or is it better to make it programmatically? Thank you very much for your help!
I don't know for a way to do this only with interface builder, but the IB can help you. I will do it creating another view controller which contains the view you want to be shown. On your already existing view controller you can create a method i.e:
- (void) show: (id) sender {
UIViewController *theNewController = [TheNewController alloc] initWithNibName: #"TheNewController" bundle:[NSBundle mainBundle]];
[self presentViewController:theNewController animated:YES completion:nil];
}
and link this method, using the IB, to the button actions.(right click on the button in IB, choose the event i.e Touch Down, drag'n drop to the File's Owner). But I recommend you also seeing view controller's apple documentation: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html
I would like to ask a question.
Now i'm training about iPhone Programming.
I'm just new baby in iOS Programming.
I want to add navigationbar in UIPickerView's upper place.
It's like the UINavigationBar in MainView.
I just want to add on UIPickerView.
and also i want to add Done button in that NavigationBar.
After i touched that done button, my view will back to main view.
How can i do that?
Please answer me if you know.
I hope you understand my question.
Sorry for my bad english.
Thanks you for reading.
All you do is drag a navigation bar on the top of the uipicker. Im assuming your wanting this UIPicker to popup, so just create a view just for the picker, drag in a navigation bar and uipicker into the view, then adjust the size of your view window for the bar and uipicker. THen you just need to hookup the the bar and uipicker to file's owner as delegates. Make sense?
When I understand you correct, you have one navigation controller and want to add to this navigation controller a new UIView with a UIPickerView which comes up after pushing the edit Button and hide when you press done button?
Then I would create a new UIViewController in Interface Builder, add the UIPickerView to this View. Put this in the correct place. In the new view controller add a property of type UIPickerView and connect the IBOutlet of PickerView to the FilesOwners Property. In the Controllers method viewDidLoad you set then for example:
[self.datePicker setHidden: YES];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
This button calls automatically the method setEditiong: on pushing. You can reimplement it for example:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
if (editing) {
[self.datePicker setHidden:NO];
} else {
[self.datePicker setHidden:YES];
}
}
I'm trying to build an app that features a button on the first view, when you tap the button it presents the UIImagePickerController modal view. What I would ideally like is once you have taken you photo, when the modal view is dismissed, the original view which presented the image picker changes.
For example, the process would be VIEW 1 -- (tap button) --> MODAL IMAGE PICKER -- (close modal view) --> VIEW 2.
So far I've got the app loading the UIImagePickerController and once you are complete, within the didFinishPickingMediaWithInfo delegate method, it sets a BOOL value to YES and then within the ViewDidAppear of my original view (VIEW 1) it then presents a new modal with the next view.
The problem with this is that there is a delay between the closing the modal view and the next view (VIEW 2) appearing.
Does anyone know if the above is possible? If not, I might have to resort to displaying a spinner and saying "Processing image" between the image picker closing and the second view appearing.
You can use a navigation controller to solve this problem.
Create a navigation controller and push your first controller into it. Later from your first controller, present the picker modally. Pretty much the same until now except that we have added a navigation controller. This is what I did to get your desired result.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NewController *controller = [[NewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:controller animated:YES];
[self dismissModalViewControllerAnimated:YES];
[controller release];
}
Hope this helps.
I have a simple uiviewcontroller with 4 buttons. Every buttonclick event loads a different image on the view. However for the 4th button i want to launch a navigation controller based uiview with a uitableview. The table view can then have 3 levels which define the settings for the application.
On selecting a row in the uitableview on the 3rd level i need to return to my main view with the selected row index.
How can i add a navigation based view which will be launched on a button press event and the first view of the uinavigationcontroller should compose of a back button which will close this navigation view and return to main view.
TIA,
Praveen S
Edit:
My first(home) view does not need a navigation bar. The view launched from the home view should however consist of a navigation bar with back button.
if(nxtv12==nil){
nxtv12=[[v12 alloc] initWithNibName:#"v12" bundle:nil];
}
[self.navigationController pushViewController: nxtv12 animated:YES];
and for coming back to home.
[self.navigationController popToRootViewControllerAnimated:YES];
Create a UINavigationViewController object in the current UIViewController (or use self.navigationcontroller) and push the new UIView into the navigation controller. To come back to the same view, use popToRootViewControllerAnimated in the new UIView class.