How can I create a UIPopoverController with integrated UINavigationController so I will be able to slide views inside the UIPopoverController left-right (with navigation bar).
UPDATE:
I open popup like this
- (void)showSettingsViewAtSenderForIPad:(id)sender
{
if (!settingsPopoverController_)
{
SettingsPopoverController *settings = [[SettingsPopoverController alloc] init];
settings.valuesGeneratorOptions = valuesGeneratorOptions_; // setting variables
self.settingsPopoverController_ = [[[UIPopoverController alloc] initWithContentViewController:settings] autorelease];
[settingsPopoverController_ setDelegate:self];
[settingsPopoverController_ setPopoverContentSize:CGSizeMake(320, 480)];
[settings release];
}
if (!infoPopoverController_.popoverVisible)
{
[settingsPopoverController_ presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];
}
}
I created a controller which has a NSTableViewController as a root controller in UINavigationController
#interface SettingsPopoverController : UIViewController
{
ValuesGeneratorOptions *valuesGeneratorOptions;
IBOutlet SettingsViewController *settingsViewController;
IBOutlet UINavigationController *navigationController;
}
...
#implementation SettingsPopoverController
...
- (void)viewDidLoad
{
self.settingsViewController.valuesGeneratorOptions = self.valuesGeneratorOptions;
[self.view addSubview:self.navigationController.view];
[super viewDidLoad];
}
...
end
The problem is, that the table is not scrollable inside the popup. It also ignores the table style (initWithStyle not called).
Fix?
SOLUTION:
Found the solution: popOver table view
You create a new nib and a UIViewController. This nib has, as it's top level view, a plain jane UIView and a UINavigationController. The UINavigationController's top UIViewController is whatever view controller you want to display first.
You then display this nib inside your popover controller. In the view did load, you do something like this:
-(void)viewDidLoad
{
[self.view addSubview:self.navigationController.view];
}
This adds your navigation controller's view to your view in your nib, which allows it to be displayed.
Related
I'm trying to implement SWRevealViewController on this scenario:
From my main viewController:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SWRevealViewController *SWR = [storyboard instantiateViewControllerWithIdentifier:#"SWRevealViewController"];
[self presentViewController:SWR animated:YES completion:nil];
}
From my green view controller:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
self.reveal = [[SWRevealViewController alloc] init];
self.reveal.delegate = self;
self.menu.target = self;
self.menu.action = #selector(revealToggleAction:);
[self.view addGestureRecognizer:self.reveal.panGestureRecognizer];
NSLog(#"viewDidLoad");
}
-(void)revealToggleAction:(id)sender
{
[self.reveal revealToggle:self];
}
The revealToggle action is been call but doesn't do anything. It doesn't load the rear view controller. Any of you knows this happening or what I'm doing wrong?
Assuming that you are showing the side bar menu from right side.
First Embed your first view controller to navigation controller, then in your first view controller viewdidload() or viewDidAppear method add below mentioned code i.e.
//this is your side menu view controller.
UIViewController *sideMenuController =
[self.storyboard instantiateViewControllerWithIdentifier:#"YourSideMenuIdentifier"];
//this is the navigation controller embed to your green view controller.
UINavigationController *nc1 =
(UINavigationController *)[self.storyboard instantiateViewControllerWithIdentifier:#"YourNavigationControllerIdentifier"];
//This is your reveal view Controller.
SWRevealViewController *revealViewController =
[[SWRevealViewController alloc]initWithRightViewController:sideMenuController frontViewController:nc1];
[self.navigationController pushViewController:revealViewController animated:YES];
[self.navigationController setNavigationBarHidden:YES];
This will navigate to Controller i.e Green View Controller.
then in your green view controller viewdidload() or viewDidAppear method add below mentioned code i.e.
//GreenViewController.h file
#interface GreenViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIBarButtonItem *sideBarItem;
#end
//Your GreenViewController.m file
_sideBarItem.target = self.revealViewController;
_sideBarItem.action = #selector(rightRevealToggle:);
SWRevealViewController *revealController = [self revealViewController];
[self.view addGestureRecognizer:revealController.panGestureRecognizer];
Note: For more details, check below mentioned link
http://www.appcoda.com/ios-programming-sidebar-navigation-menu/
You need set SWRevealViewController is the initial view controller.
You are creating a new instance of SWRevealViewController.
I think if you set the self.reveal to self.revealViewController it will work.
I don't know if this is the right key to search "add UIViewController in subview".
As what you can see in my image ,there are two ViewController, the main and the second controller. Inside the main controller there is a UIView(blue background color). Inside in UIView, I want to add the second ViewController in my UIView. I have this code but It didn't work.
here's my code
#import "ViewController.h"
#import "SampleViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIView *testView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
SampleViewController * sample = [[SampleViewController alloc] initWithNibName:#"SampleViewController" bundle:nil];
sample.view.frame = CGRectMake(0, 0, self.testView.bounds.size.width, self.testView.bounds.size.height);
[self.testView addSubview:sample.view];
}
#end
I want to know if this is possible? I know initWithNibName: works in xib file, I don't the exact term to search in google about this. I'm just trying to experiment something if this is possible in IOS. Hoping you understand what I'm trying to do. Hoping for your advice. Thanks in advance
here's my update
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIView *testView;
#property(strong,nonatomic) SampleViewController * samples;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIStoryboard *storyBoard = self.storyboard;
SampleViewController * sample = [storyBoard instantiateViewControllerWithIdentifier:#"SampleViewController"];
// SampleViewController * sample = [[SampleViewController alloc] //initWithNibName:#"SampleViewController" bundle:nil];
[self displayContentController:sample];
//commented the below line because it is not needed here, use it when you want to remove
//child view from parent.
//[self hideContentController:sample];
}
- (void) displayContentController: (UIViewController*) content;
{
[self addChildViewController:content]; // 1
content.view.bounds = self.testView.bounds; //2
[self.testView addSubview:content.view];
[content didMoveToParentViewController:self]; // 3
}
- (void) hideContentController: (UIViewController*) content
{
[content willMoveToParentViewController:nil]; // 1
[content.view removeFromSuperview]; // 2
[content removeFromParentViewController]; // 3
}
I always get this error
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/ace/Library/Developer/CoreSimulator/Devices/035D6DD6-B6A5-4213-9FCA-ECE06ED837EC/data/Containers/Bundle/Application/EB07DD14-A6FF-4CF5-A369-45D6DBD7C0ED/Addsubviewcontroller.app> (loaded)' with name 'SampleViewController''
I think, its looking for a nib. I didn't implement a nib here.
You should use Child containment concept, here MainViewController is a parent view controller and you want to add child view controller view as a subview on Main View Controller.
Adding and Removing a Child
//call displayContentController to add SampleViewCOntroller view to mainViewcontroller
[self displayContentController:sampleVCObject];
// write this method in MainViewController
- (void) displayContentController: (UIViewController*) content;
{
[self addChildViewController:content]; // 1
content.view.bounds = testView.bounds; //2
[testView addSubview:content.view];
[content didMoveToParentViewController:self]; // 3
}
Here’s what the code does:
It calls the container’s addChildViewController: method to add the child. Calling the addChildViewController: method also calls the child’s willMoveToParentViewController: method automatically.
It accesses the child’s view property to retrieve the view and adds it to its own view hierarchy. The container sets the child’s size and position before adding the view; containers always choose where the child’s content appears. Although this example does this by explicitly setting the frame, you could also use layout constraints to determine the view’s position.
It explicitly calls the child’s didMoveToParentViewController: method to signal that the operation is complete.
//you can also write this method in MainViewController to remove the child VC you added before.
- (void) hideContentController: (UIViewController*) content
{
[content willMoveToParentViewController:nil]; // 1
[content.view removeFromSuperview]; // 2
[content removeFromParentViewController]; // 3
}
For more details, please refer to apple doc:
https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html
Configuring a Container in Interface Builder, for those who don't want to write code.
To create a parent-child container relationship at design time, add a container view object to your storyboard scene, as shown in Figure 5-3. A container view object is a placeholder object that represents the contents of a child view controller. Use that view to size and position the child’s root view in relation to the other views in the container.
When you load a view controller with one or more container views, Interface Builder also loads the child view controllers associated with those views. The children must be instantiated at the same time as the parent so that the appropriate parent-child relationships can be created.
You can do this simply by using StoryBoards
Open storyboards and select the view controller in which your Blue view is present, open Utilities search for ContainerView and drag it into your blue view, this will automatically adds an view controller that acts as child view for your view. You can resize your container view in size inspector.
I've resolved the problem about the uiview on second uiviewcontroller.
Follow the code that I've used:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *sb = (SecondViewController *)[storyboard instantiateViewControllerWithIdentifier:#"sb"];
sb.view.backgroundColor = [UIColor redColor];
[sb willMoveToParentViewController:self];
[self.view addSubview:sb.view];
[self addChildViewController:sb];
[sb didMoveToParentViewController:self];
I hope to help you.
Thanks a lot
SampleViewController * sample = [[SampleViewController alloc] initWithNibName:#"SampleViewController" bundle:nil];
sample.view.frame = CGRectMake(0, 0, self.testView.bounds.size.width, self.testView.bounds.size.height);
[self addChildViewController:sample];
[self.testView addSubview:sample.view];
You can add a childViewController to UIViewController since iOS5..
it is a great way to maker smaller, more reusable viewControllers, I also really like it.
you're really close, but you just need a couple more lines of code..
///
[self addChildViewController:sample];
[self.testView addSubview:sample.view]; //you already have this..
[sample didMoveToParentViewController:self];
In you viewWillDisappear: or one of the other teardown methods you'll need to clean up like this:
//we'll need another pointer to sample, make it an iVar / property..
[sample willMoveToParentViewController:nil]; // 1
[sample removeFromSuperview]; // 2
[sample removeFromParentViewController]; // 3
You can read the Apple docs on containing child viewControllers here https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html
I'm tring to adding UIViewController in subview, and this work.
On UIViewController I've added 2 button, in .h file:
-(IBAction)matchButtonAction:(id)sender;
-(IBAction)closeButtonAction:(id)sender;
And in .m file:
-(IBAction)matchButtonAction:(id)sender
{
NSLog(#"matchButtonAction");
}
-(IBAction)closeButtonAction:(id)sender
{
NSLog(#"closeButtonAction");
}
but I don't see the log.
I need to add same parameter on UIViewController instantiateViewControllerWithIdentifier?
How to resolve the problem?
My UIViewController initialization is:
AlertDialogViewController *alertDialogView = (AlertDialogViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"alertDialogView"];
[alertDialogView willMoveToParentViewController:self];
[viewController.view addSubview:alertDialogView.view];
[viewController addChildViewController:alertDialogView];
[alertDialogView didMoveToParentViewController:viewController];
Since your view controller is in storyboard you should use instantiateViewControllerWithIdentifier to get the VC from storyboard.
SampleViewController * sample = [self.storyboard instantiateViewControllerWithIdentifier:#"IdOfSampleViewController"];
sample.view.frame = CGRectMake(0, 0, self.testView.bounds.size.width, self.testView.bounds.size.height);
[self.testView addSubview:sample.view];
Don't forget the add the identifier for the SampleViewController in storyboard
I've try to use this code:
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
secondViewController.view.frame = CGRectMake(0, 0, self.mySubView.bounds.size.width, self.mySubView.bounds.size.height);
[self addChildViewController:secondViewController];
[self.viewDialogSolution addSubview:secondViewController.view];
but I see only myview not the layout of secondViewController.
Ho to resolve the probleam?
Thanks a lot
let controller:SecondViewController =
self.storyboard!.instantiateViewController(withIdentifier: "secondViewController") as!
SecondViewController
controller.view.frame = self.view.bounds
controller.willMove(toParent: self)
self.view.addSubview(controller.view)
self.addChild(controller)
controller.didMove(toParent: self)
In an iOS app at work, we have a view controller which presents another as a modal.. Something like:
-(void)didTapOnStartButton {
MyViewController *myView = [[MyViewController alloc] init];
[self presentViewController:myView animated:YES completion:nil];
}
And then the view controller instantiates a navigation controller and puts another view controller on it... something like:
#interface MyViewControler()
#property (nonatomic, strong) UINavigationController *childNav;
#end
#implementation MyViewControler
-(void)viewDidLoad {
OtherViewController *otherController = [[OtherViewController alloc] init];
self.childNav = [[UINavigationController alloc] initWithRootViewController:otherController];
[self.view addSubview:childNav.view];
childNav.view.frame = self.view.frame;
}
... This results in the presented view controller having a navigation bar (as I want), however it's height is wrong. I experimented a lot with the frame, tried offsetting its Y origin by -22px, but the OtherViewController is a table view controller, and its contents end up being -22px off the screen (covered up by the navigation bar). So I am not quite sure why this is happening, and how to fix it.
Any help would be greatly appreciated.
My goal is to create an application which features the camera as the first view that appears and then after taking a picture goes to a series of views which are in a navigation controller. The closest existing application to what I want to make is Snapchat.
I've been struggling with this for several days, here's what I have tried (none of these seem to work).
Root View (Inside Navigation Controller) Presents a Modal UIImagePickerController and then segues to next view. [Does not segue]
Same as 1, but dismiss the modal controller then segue. [Kinda Works. Shows the background when loading the UIImagePicker and also when transitioning to the next view]
Use a subclass of UIIMagePickerController as the root view.[Works but does not allow navigation bar to be shown or else crashes on displaying the UIImagePickerController][
Use 3 and don't embed inside a navigation controller (reasoning: since UIImagePickerController is a subclass of navigation controller this should work). [Does not work.]
I've tried about 10 other ways to do the same thing and they fall in this category: [Kinda Works. Most crash or look look ugly].
What is the best way to do this? Any help or advice would be greatly appreciated!
Again if this is confusing, just open snapchat and play with the flow (same flow, totally different idea for the actual app - ie. not a snapchat clone :)
Thanks!
If you present the image picker modally from the navigation controller's root view controller with no animation, then the picker is what you will see first. When you dismiss it, you'll see that root controller, which should be what ever you want to see first when the picker goes away. Is that what you want? This code would be in the root controller:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
static int first = 1;
if (first) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = 0;
[self presentViewController:picker animated:NO completion:nil];
first = 0;
}
}
1st Suggestion:
Make one mainController and add the buttons(depends on how many viewController you have), when button clicked each button will load different viewController.
// appDelegate.h
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) MainViewController *mainController;
//appDelegate.m
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.mainController = [[[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
//each button clicked has following IBAction:
-(IBAction)button1Clicked:(id)sender
{
FirstViewController *firstVC = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:[NSBundle mainBundle]];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:firstVC]autorelease];
[self presentModalViewController:navController animated:NO];
[addVC release];
}
//in FirstViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
self.title = #"xxxx ";
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancel_Clicked:)]autorelease];
}
-(void) cancel_Clicked:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
Note :
ViewController to be embedded inside a navigation controller, the following code has to be used;
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:firstVC]autorelease];
I have a navigation based application.On click of a button on the navigation bar in the first screen , I am able to push another view controller as follows :
-(void) buttonClicked:(id)sender
{
UIViewController* mv = [[SecondViewController alloc] init];
[[self navigationController] pushViewController:mv animated:YES];
}
Now i have a UIView(separate .h and .m files) as part of the first screen. On click of a button in the UIView, i want to push the SecondViewController.
I have tried the following :
UIViewController* mv = [[SecondViewController alloc] init];
UIViewController * home=[[FirstViewController alloc]init];
[[home navigationController] pushViewController:mv animated:YES];
It doesnt work!! Kindly help
UIViewController* mv = [[SecondViewController alloc] init];
UIViewController * home=[[FirstViewController alloc]init];
[[home navigationController] pushViewController:mv animated:YES];
The problem here is that home isn't part of the navigation stack, so [home navigationController] is surely nil. I'm not quite clear on what you're trying to do here, but just creating a view controller doesn't mean that it's actually part of the view controller graph.
Why would it work? Randomly creating view controllers whose view is not even visible, is not the solution. You can either keep a reference to the VC in the view like this:
#imlementation ViewController
- (id) init
{
// ...
aView = [[CustomView alloc] init];
aView.viewController = self;
// ...
}
#end
#interface CustomView
#property (assign) ViewController *viewController;
#end
Or you can search the responder chain at runtime:
UIResponder *next = [view nextResponder];
while (next)
{
if ([next isKindOfClass:[ViewController class]])
{
break;
}
next = [next nextResponder];
}
And now "next" will contain the view controller (or nil if it can't be found).
Try using the same navigationController to push view, this keeps the same stack of ViewControllers.
UIViewController* mv = [[SecondViewController alloc] init];
[[self navigationController] pushViewController:mv animated:YES];
[mv release];
I see your problem now! You need to #import your FirstViewController, then #class it. Then do your push.
So:
//.h
#import "FirstViewContoller.h"
#class FirstViewController;
#interface...
//.m
-(void)return {
FirstViewController *firstview = [[FirstViewController alloc]init(withnibname:)];
[firstView.navigationController pushViewController: firstView.navigationController.topViewController animated: TRUE];
}
If I am not wrong, your UIView though is in separate files, is still added to the screen from a UIViewController class.
Simply, post a notification from UIView to your FirstViewController class where you have access to the navigation controller. Then push the SecondViewController from there.
You Can use this. It Works very well for me:-
Firstly Create Object of AppDelegate in UIView Class and initialize it. Then create Navigationcontroller object in Appdelegate.h :-
#property(strong,nonatomic) UINavigationController *navControl;
In your UIView Class implement this code where you want to push :-
ViewController *objview = [[ViewController alloc]init]; [appDelegate.navControl pushViewController:objview animated:YES];