UISplitViewController in portrait: how to hide master popover programmatically? - objective-c

In my UISplitViewController the master controller is a UINavigationController.
When in portrait mode I would like to keep the navigation controller visible as long as the user navigates upwards (using the back button). As soon as an item from the table view of the navigation controller is selected, I want to dismiss the popover.
How can I achieve this? How can my UITableViewController know if it is inside a popover, and if yes, dismiss itself?

Make your main view controller a UISplitViewControllerDelegate (if it isn't already) and wire it up to the UISplitViewController's delegate outlet.
Create a UIPopoverController variable in your main view controller:
// MyViewController.h
#interface MyViewController : UIViewController <UISplitViewControllerDelegate> {
UIPopoverController *popoverController;
}
#property (retain, nonatomic) UIPopoverController *popoverController;
// MyViewController.m
#synthesize popoverController;
Implement the following UISplitViewControllerDelegate methods:
// Called when rotating to portrait
- (void)splitViewController:(UISplitViewController*)svc
willHideViewController:(UIViewController *)aViewController
withBarButtonItem:(UIBarButtonItem*)barButtonItem
forPopoverController:(UIPopoverController*)pc {
// Popover controller is visible in portrait
self.popoverController = pc;
}
// Called when rotating to landscape
- (void)splitViewController:(UISplitViewController*)svc
willShowViewController:(UIViewController *)aViewController
invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
// No popover controller in landscape view
self.popoverController = nil;
}
In your own handler in the main view controller (the one that gets called when a naviation item is selected in the table view):
- (void)navigationControllerSelectedItem:(id)item {
// If a popover controller is visible, hide it
if (popoverController) {
[popoverController dismissPopoverAnimated:YES];
}
}
And don't forget to release that variable:
- (void)dealloc {
self.popoverController = nil;
[super dealloc];
}
Hope that helps!

The standard iPad sample for SplitViewController in iOS5 does about the same as the elaborate answer, but the popoverController is called masterPopoverController.
And creating the property iOS5 style as _popoverController does not work, because there as already an ivar with that name in UIViewController.h.

The IOS 6.0 SplitView template has this built in. The detail view tracks the orientation and the MasterViewController popover.
Simply set the detailItem and the popover disappears if appropriate. There is even a check if you are using the same detaiItem so no page setup and refresh work gets done.
self.detailViewController.detailItem = self.detailViewController.detailItem;

Related

objective-c OSX class inheritance

I have a method “ShowPop:nil” in a “Navigation” class - it displays a popover.
I have inherited the Navigation class from the AppDelegate.h. When I call [Self ShowPop:nill] from AppDelegate.m the popover wont pop but the method does run.
Note, I know the popover method works because it pops perfectly from a IB button connection from the same method.
Sample code below.
#interface Navigation_Main : NSObject
{
}
#property (weak) IBOutlet NSPopover *popover_AddStuff;
- (IBAction)ShowPop:(id)sender;
- (IBAction)ShowPop:(id)sender;
{
[_popover_AddStuff showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxYEdge];
}
.
**#import "Navigation_Main.h"**
#interface AppDelegate : Navigation_Main <NSApplicationDelegate,NSTextFieldDelegate>
{
- (IBAction)showPopup:(id)sender;
}
- (IBAction)showPopup:(id)sender {
//[self ShowPop:nil]; ---No pop
[super ShowPop:nil]; ---No pop
}
NSPopover throws an exception when the positioning view is nil, and (as a consequence) won't show the popover. Ensure you pass a view for the popover to be shown relative to, not nil.

initWithNibName : I have no scroll and no navigation bar?

So I've a button with a IBAction heading to another ViewController by its initWithNibName method. Everything is embedded in a NavigationController.
I also created a .xib for this ViewController, here is a quick screenshot :
Here is my code :
.h
#interface ModeEmploiController : UIViewController
{
IBOutlet UIScrollView *scrollView;
UITextView *vueOffres, *vueInfos, *vueGrilles;
}
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
.m
#implementation ModeEmploiController
#synthesize scrollView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
[scrollView setScrollEnabled:YES];
[scrollView setContentSize:CGSizeMake(320, 529)];
// Here I define vueOffres, vueInfos and vueGrilles and for each of them :
[self.view addSubview:vueGrilles/vueInfos/vueOffres];
}
}
But when I run my app, my scroll isn't enabled and I don't have the navigation bar of my navigation controller. What's happening?
add another view inside the ScrollView i called mine content view. the do
self.scrollView.contentSize = self.contentView.frame.size;
for the navigation bar you need to have a uinavigation controller and make your controller the rootviewcontroller of the navigation controller. like this
-(IBAction)MyButton:(id)sender
{
MyViewController *controller = [[MyViewController alloc] initWithNibName:#"MyView" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
[self.navigationController presentModalViewController:navController animated:YES];
}
Remove your ModeEmploiController from xib, but keep its child View and ScrollView.
now click on File's Owner and put ModeEmploiController from Identity inspector in right panel.
Now right click on File's Owner and connect property of view to View and scrollView to ScrollView.
Your initialization code is in the wrong method.
Since you are using Storyboards, your view controller is being unarchived from a nib file. The correct place to initialize the controls is in the awakeFromNib method.
Make sure that you have set up an IBOutlet property for your scroll view and hooked it up in the Storyboard, and then:
- (void)awakeFromNib {
[self.scrollView setScrollEnabled:YES];
[self.scrollView setContentSize:CGSizeMake(320, 529)];
// Here I define vueOffres, vueInfos and vueGrilles and for each of them :
[self.view addSubview:vueGrilles/vueInfos/vueOffres];
}
That just leaves the problem of the subview that you are adding. What is vueGrilles/vueInfos/vueOffres? You should create this view properly within the viewDidLoad method and add it as a subview there instead of in this initialiser.

ViewControllers Navigation

I have one base view controller "contentViewController" with one button
the action on button is
(IBAction) goBack:(id)sender
.h file
#interface ContentView : UIViewController {
}
#property(nonatomic,retain) UIViewController *display;
-(IBAction) goBack:(id) sender;
.m file
#synthesize display;
-(IBAction) goBack:(id)sender{
UIViewController *view= display;
[display release];
[self presentModalViewController:view animated:YES];
}
and there are some other view controllers already exist each view controller contain on button to show content on the contentViewController.. here is one class example:
.h file
#interface Info : UIViewController {
}
-(IBAction) viewHealthInfoContent:(id) sender;
.m file
-(IBAction) viewHealthInfoContent:(id)sender{
ContentView *cv=[ContentView alloc];
[cv setDisplay:self];
[self presentModalViewController:cv animated:YES];
[cv release];
}
the case is, each time i show content from one view controller i need to go back to it. using that one goBack button on the contentViewController but when i click the go back button it doesn't do any think !!! any help
When you want to go back your previous viewController, use dismissModalViewControllerAnimated:: method.
According source :
Dismisses the modal view controller that was presented by the receiver.
In iOS, you can display views modally by presenting the controller for the modal view from your current view controller. When you present a view modally using the presentModalViewController:animated: method, the view controller animates the appearance of the view using the technique you specify. (You can specify the desired technique by setting the modalTransitionStyle property.) At the same time, the method creates a parent-child relationship between the current view controller and the modal view controller.
Source

(Xcode) Links Between UIButtons and pages

Hey guys I'm a newbie developer with cocoa and I'm Trying to create a simple app. which display 4 differents pages that you can select via a tab bar.
My Problem: I made a UIButton on the First/Home page (==>FirstView.xib) with IB and i tried to link it to my second page (==>SecondView.xib) with some code found on the net.
The thing is that i can build my code but nothing happens when I try to click on my button, can you help me ?
Code for FirstView.h:
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController {
UIButton *button;}
#property (nonatomic, retain) IBOutlet UIButton *button;
- (IBAction)goToViewTwo;
#end
Code for FirstView.m:
#implementation FirstViewController
#synthesize button;
- (IBAction)goToViewTwo {
SecondViewController *SecondView= [[SecondViewController alloc] initWithNibName: #"SecondView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:SecondView animated:YES];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)dealloc {
[super dealloc];
[button release];
}
#end
About the outlets in FIrstVIew.xib:
I linked "Touch Up Inside" to "goToViewTwo" and "b^utton" to "File's Owner'
I'm under the impression this is in a tab bar where each tab bar button displays a .xib file. If this is the case, the solution is fairly simple. Your tabBarController manages your views in an array of view controllers. To switch between them, your IBAction method should be the following:
- (IBAction)goToViewTwo {
self.tabBarController.selectedIndex = 1;
}
This tells your tab bar controller to switch from your current view controller (at index 0) to the second (at index 1)

How can I use a single UIToolbar with multiple different UIViewControllers?

I have a simple app with two basic screens, a UIMapView and a UITableView. I'd like to have a toolbar at the bottom with a couple of buttons and a UISegmentedControl with two segments: "Map" and "Table". (The layout is similar to the Google Maps app that ships with the iPhone.) How can I keep the same toolbar while presenting either the UIMapView (with a UIMapViewController) or the UITableView (with a UITableViewController) when the user switches back and forth on the segmented control? Of course, I can just create an identical toolbar for each of the two different views and display them separately, but is there a better way?
Write a UIViewController that manages your 2 VC's and transitions between the MKMapView and UITableView in response to the segmented control.
First set up the nib for this new VC in Interface Builder: add an UISegementedControl and a simple UIView (contentView).
The interface file contains references to the UI Elements and to the 2 VC's + an action to respond to the segmented control:
//
// MapAndTableViewController.h
//
#import <UIKit/UIKit.h>
#import "MyMapViewController.h"
#import "MyTableViewController.h"
#interface MapAndTableViewController : UIViewController {
IBOutlet UISegmentedControl* segmentedControl;
IBOutlet UIView* contentView;
UIViewController* firstVC;
UIViewController* secondVC;
}
-(IBAction) valueChanged:(UISegmentedControl*) sender;
#end
Implementation:
//
// MapAndTableViewController.m
//
#import "MapAndTableViewController.h"
#implementation MapAndTableViewController
-(IBAction) valueChanged:(UISegmentedControl*) sender {
if (sender.selectedSegmentIndex == 0) {
[UIView transitionFromView:[contentView.subviews lastObject] toView:firstVC.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
}
if (sender.selectedSegmentIndex == 1) {
[UIView transitionFromView:[contentView.subviews lastObject] toView:secondVC.view duration:0.5 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
}
}
-(void)awakeFromNib {
firstVC = [[MyMapViewController alloc] initWithNibName:#"MyMapViewController" bundle:nil];
secondVC = [[MyTableViewController alloc] initWithNibName:#"MyTableViewController" bundle:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
[contentView addSubview:firstVC.view];
}
- (void)dealloc {
[firstVC release];
[secondVC release];
[super dealloc];
}
#end
In the valueChanged method you replace the current view and animate the transition.
Note that the views firstVC.view and secondVC.view are created on first access of the view-property of each VC.
you could use a single view controller, and add all of the views(UIMapView, UITableView, etc) to your view and simply show/hide the correct views upon clicking the segmented control
with such a simple app without many views, you shouldn't have a messy/clustered view controller file and can easily show/hide these 2 views.
perhaps use an animation between switching between views so it looks nice