I am creating a viewcontroller in this way:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"PhotoViewControlleriPhone" bundle:nil];
UIViewController *vc = [sb instantiateInitialViewController];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:vc animated:NO];
vc.view.frame = CGRectMake(imageView.frame.origin.x, imageView.frame.origin.y + 64, imageView.frame.size.width, 200.000000);
vc.view.layer.cornerRadius = 10; // this value vary as per your desire
vc.view.clipsToBounds = YES;
The viewcontroller is not full screen, so you can still see the previous one. I want to be able to see it, but lock it. Just like when you use ios facebook sharing, you see the background, but it becomes darker and you can't interact with it. How can I do this?
I believe the problem is that you’re displaying it using -presentModalViewController:animated:. Using that method carries with it some assumptions about the view controller you’re hosting; one of the assumptions it makes (on iPhone-type devices, at least) is that the view controller takes up the entire screen and is opaque.
To get around this, try adding the modal view controller’s view to the current view controller’s view manually. You’ll need to set the view controller hierarchy up to match the view hierarchy, so your code would look like this:
[self addChildViewController:vc];
[self.view addSubview:vc.view];
You’ll need to adjust the incoming view’s frame to position it within its new superview, but that should allow you more freedom.
My workaround is to take a screenshot with code, pass the UIImage as a parameter to the new UIViewController, and display it as a background image. In that way it appears transparent, and the you don't have to disable the underlying controls that might be reachable/accessible.
iOS8+
You can use below code snippet for iOS8+, its worked for me
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:secondViewController animated:YES completion:nil];
Related
I am putting a UINavigationController inside a container view like so (this in a full screen UIViewController subclass):
UIViewController *litteViewController = [[UIViewController alloc]initWithNibName:nil bundle:nil];
UINavigationController *littleNavigator = [[UINavigationController alloc]initWithRootViewController:litteViewController];
UIView *containerView = [[UIView alloc]initWithFrame:CGRectMake(100.0, 100.0, 250.0, 320.0)];
littleNavigator.view.frame = containerView.bounds;
[self addChildViewController:littleNavigator];
[containerView addSubview:littleNavigator.view];
[self.view addSubview:containerView];
[littleNavigator didMoveToParentViewController:self];
Now this works as expected and littleViewController appears in the rect I expect with a nav bar at top. Now let us say as a result of some interaction inside littleViewController something like this happens
-(void)someButtonAction:(id)sender{
UIViewController *secondLittleViewController = [[UIViewController alloc]initWithNibName:nil bundle:nil];
[self.navigationController presentModalViewController:secondLittleViewController animated:YES];
}
unfortunately this subsequent controller winds up being presented full screen. Now I've done exactly this before inside popoverControllers and splitViewControllers and they've behaved exactly as I want this to, a navigation stack is built within the little rectangle it was started in.
How can I build a navigation stack inside a container over in an arbitrary CGRect?
On iPhone and iPod touch, the presented view is always full screen. So you need change to pushViewController
Glad I can help
That simple example but that don't work;
I have ViewController where inside on NavigationConroller, then I want to add new ViewConroller with its self navigation controller.
In main viewController:
CustomViewController *vc = [[CustomViewController alloc] init];
NewNavigationVC *nav = [[NewNavigationVC alloc] initWithRootViewController:vc];
[self presentViewController:nav animated:NO completion:nil];
Two controllers has a background color clear, but still black color.
Navigation bar I can do clear, but not a view.
UPDATE:
if i change self.window.backroundColor to red for example, that work but not clear
UPDATE 2:
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];
and when I want to dealloc vc
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
All work ok without navigation controller
A viewController's view's backgroundColor can't be clear (as in showing the previous viewController's view on the stack). Pushing or presenting a viewController will put the new viewController on the stack and hide the previous viewController completely.
If you want a clear backgroundColor on the view, you will need to either:
1) set the viewController as a childViewController of the previous viewController - then animate the transition yourself.
Or
2) transplant the viewController logic into the previous viewController and have a new uiview act as that view (you also need to animated the transition yourself).
The solution is as follows. For clear example we use tableViewController:
UITableViewController *modalVC = [UITableViewController new];
UINavigationController *modalNVC = [[UINavigationController alloc] initWithRootViewController:modalVC];
UIViewController *mainVC = [UIViewController new];
UINavigationController *mainNVC = [[UINavigationController alloc] initWithRootViewController:mainVC];
modalVC.view.backgroundColor = UIColor.clearColor;
mainVC.view.backgroundColor = UIColor.redColor;
mainNVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[mainNVC presentViewController:modalNVC animated:YES completion:NULL];
The key feature is that you have to set modalPresentationStyle of presentingViewController to UIModalPresentationCurrentContext.
It works fine BUT without slide animation. You will get result immediately.
But you can still use "blood hack" to retain visual animation by successive presenting, dismissing and presenting again:
modalVC.view.backgroundColor = UIColor.clearColor;
mainVC.view.backgroundColor = UIColor.redColor;
[mainNVC presentViewController:modalNVC animated:YES completion:^{
[modalNVC dismissViewControllerAnimated:NO completion:^{
mainNVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[mainNVC presentViewController:modalNVC animated:NO completion:NULL];
}];
}];
You basically need to tell the navigation controller to:
navigation.modalPresentationStyle = .overCurrentContext
In other words:
A presentation style where the content is displayed over another view controller’s content.
and that's it.
You can also make sure that:
navigation.view.backgroundColor = .clear
When i press a button on my view controller, i would like to present another controller on top of it, but in the middle and not in full screen.
How could i present a controller on top of another controller in such way?
If you are trying it on iPad you can always set up a Popover that contains your new view.
UIYourNewViewController *vc = [[UIYourNewViewController alloc] init];
UIPopoverController *popVc = [[UIPopoverController alloc] initWithContentViewController:vc];
[popVc setPopoverContentSize:*the size that you want or your resized vc*];
[popVc presentPopoverFromRect:*position of the screen you want to show the popover* inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
With this you will create a Popover of the size of the view of your viewcontroller and you can pop it up in the position that you want.
To make sure it works on iPhone also, you should create a category for the UIPopoverController and add this method in the .m
+ (BOOL)_popoversDisabled {
return NO;
}
Remember to declare the method in the .h of the category.
You need to set this property to your controller before presenting it.
controller.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:controller animated:YES completion:nil];
Yes it is possible you have to present view controllers view with animation. Please refer the below code. You will get some idea its showing animation from bottom of screen to middle of screen.
YourViewController *viewController = [[YourViewController alloc] init];
[viewController.view setFrame:CGRectMake(0, -(CGRectGetHeight(viewController.view.frame)), CGRectGetWidth(viewController.view.frame), CGRectGetHeight(self.view.frame))];
[self.view addSubview:viewController.view];
[UIView animateWithDuration:0.8 animations:^{
[viewController.view setFrame:CGRectMake(0, 0, CGRectGetWidth(viewController.view.frame), CGRectGetHeight(viewController.view.frame))];
} completion:^(BOOL finished) {
[self.navigationController pushViewController:viewController animated:NO];
}];
In iPhone, presenting a UIViewController is always fullscreen. On iPad, you can use a UISplitViewController or build a custom container, but the view controllers you present will fill the containers in both a UISplitViewController and custom container controller.
To present content on only part of the screen, you can animate a UIView onto your view controller. There are ways to present a view controller and still have another view controller show up behind it, but this is not recommended.
Check out this other question for more information on creating a custom container view controller..
We instanitate a UINavigationController and a UIViewController from a storyboard like so:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"AddOrder" bundle:nil];
UIViewController *vc = [sb instantiateInitialViewController];
UIViewController *topVC = ((UINavigationController *) vc).topViewController;
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
From here, it looks like the UIViewController isn't taking up the whole UIWindow, it looks 20 pts down like on ios6. You can even see the underlying UISplitViewController's divider at the top left if you look closely.
The issue is, when the user taps an option on the UITableView on theUIViewController we call [self performSegueWithIdentifier: sender:] which pushes a new UIViewController on, but when they rotate it, it looks like so:
A little cramped, to say the least. But now, when we go back to the first UIViewController and rotate, we get this:
Issue is, the search bar is now covered. You'll notice you cannot see the underlying UISplitViewController anymore either. As you can see, it looks like now the UINavigationBar is covering up the other 20 pts and is larger in height.
I kind of "fixed" the issue by calling self.edgesForExtendedLayout = UIRectEdgeNone; but that just shoves the UIView pretty far down. I also toyed with adding [UIViewController attemptRotationToDeviceOrientation] but nothing. In Apple's HIG it states that a navigation bar should not change it's height on the iPad, yet this is happening to me when I log out the frame.
Any ideas?
Hi You can create the view controller with these properties
And add the modal on the the application window
[self.view.window.rootViewController presentViewController:vc animated:YES completion:nil];
I think your problem will be solved by this.
Just fix it by
self.automaticallyAdjustsScrollViewInsets = NO;
Put this line in viewDidLoad method and then create other controllers.
It's only working on iOS 7 and latter.
I am working on an iPhone app but found that I require another view / window to get the user to input and save data / information there.
How do I add another view? Do I add it in interface builder and then link it in the main app delegate or will it have its own .h and .m files.
I selected a window view app to start with, do I need to start over with a flip side view app or can this just be added in anyway if I have the correct code there.
manny thanks
Carl
The Window app is perfect for you. In your AppDelegate file, you should have a section like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
//instantiate the venue view controller object
YourViewController *yourViewController = [[YourViewController alloc] initWithNibName:#"YourView" bundle:[NSBundle mainBundle]];
// Configure and show the window
[window addSubview:[yourViewController view]];
[window makeKeyAndVisible];
}
This is the part of the code that declares, allocates and adds your custom view to the window. You have a couple choices for how to add the second view. You can either add it in place of this one, or add it after this one using a Navigation Controller. To add the navigation controller, change the above method to look like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
//instantiate the venue view controller object
YourViewController *yourViewController = [[YourViewController alloc] initWithNibName:#"YourView" bundle:[NSBundle mainBundle]];
UINavigationController *yourViewControllerWrapper = [[UINavigationController alloc] initWithRootViewController: yourViewController];
// Configure and show the window
[window addSubview:[yourViewControllerWrapper view]];
[window makeKeyAndVisible];
}
There, we create your custom view, then wrap it in a navigation controller. The navigation controller is what gets added to the window. Next the code to switch to the second view would look like this, assuming you switch views on a button press:
-(IBAction)switchViewController{
MySecondViewController *secondViewController = [[MySecondViewController alloc] init];
[self.navigationController pushViewController:secondViewController];
}
Of course, you should replace the line
MySecondViewController *secondViewController = [[MySecondViewController alloc] init];
with the proper way of instantiating your second view controller. This could be from a nib file like above, or programmatically.
As far as creating the view files, you should create a nib in Interface builder for the layout of everything, then create a .h and .m file for the ViewController code itself.
you can also display new frame instead of new view. It is easier sometimes, as you don;t have to pass parameters - you are in one class:
CGRect frame = okresView.frame;
frame.origin.x = frame.size.width;
if ( [okresView superview] == nil )
{
[self.view addSubview:okresView];
}
okresView.frame = frame;
[okresDataTableView reloadData]; // przeładowanie tabeli na subwidoku
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.5];
frame.origin.x = 0;
okresView.frame = frame;
[UIView commitAnimations];
if you want new subview, you can use a few methods - just download few applications from XCode help and check how they do this. Nice example are in 'Elements' and 'UICatalog' application where you have flipped view and other examples.
// Create and push another view controller.
UIViewController *myViewController = [[UIViewController alloc] init];
myViewController.title = #"My First View";
myViewController.view.backgroundColor = [UIColor redColor];
//to push the UIView.
[self.navigationController pushViewController:myViewController animated:YES];