Swift PageView navigator button set to new UIpageview - swift

I have a pageview which contains 4 pages. The pageView is using a navigation bar from previous UIViewController. I want set my UIPageView button in navigation bar to go to a new UIView. there are few problems. When i use performSegueWithIdentifier("CrankSetViewController", sender: sender) it give me a black screen. How to change to new UIView programatically without getting black screen?

In Swift -
pageViewController.setViewControllers(startingViewControllers,
direction: UIPageViewControllerNavigationDirection.Forward,
animated: true,
completion: nil)
you can set this in #IBAction
You can programmatically set the currently displayed view controller with a transition animation using setViewControllers:direction:animated:completion: on your page view controller.
Here is an example that presents view controllers with random background colors. You can adjust this to use your specific view controllers.
- (void)viewDidLoad
{
[super viewDidLoad];
self.pvc = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pvc.view.frame = CGRectInset(self.view.bounds, 200, 200);
[self.view addSubview:self.pvc.view];
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
-(UIViewController*)randomVC
{
UIViewController *vc = [[UIViewController alloc] init];
UIColor *color = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
vc.view.backgroundColor = color;
return vc;
}
- (IBAction)previousButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:nil];
}
- (IBAction)nextButtonPressed:(id)sender {
[self.pvc setViewControllers:#[[self randomVC]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}
Hope it will help you...

Related

On swipe default navigation back not working [duplicate]

I have an iOS 7 app where I am setting a custom back button like this:
UIImage *backButtonImage = [UIImage imageNamed:#"back-button"];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[backButton setImage:backButtonImage forState:UIControlStateNormal];
backButton.frame = CGRectMake(0, 0, 20, 20);
[backButton addTarget:self
action:#selector(popViewController)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
viewController.navigationItem.leftBarButtonItem = backBarButtonItem;
But this disables the iOS 7 "swipe left to right" gesture to navigate to the previous controller. Does anyone know how I can set a custom button and still keep this gesture enabled?
EDIT:
I tried to set the viewController.navigationItem.backBarButtonItem instead, but this doesn't seem to show my custom image.
IMPORTANT:
This is a hack. I would recommend taking a look at this answer.
Calling the following line after assigning the leftBarButtonItem worked for me:
self.navigationController.interactivePopGestureRecognizer.delegate = self;
Edit:
This does not work if called in init methods. It should be called in viewDidLoad or similar methods.
Use the backIndicatorImage and backIndicatorTransitionMaskImage properties of the UINavigationBar if at all possible. Setting these on an a UIAppearanceProxy can easily modify behavior across your application. The wrinkle is that you can only set those on ios 7, but that works out because you can only use the pop gesture on ios 7 anyway. Your normal ios 6 styling can remain intact.
UINavigationBar* appearanceNavigationBar = [UINavigationBar appearance];
//the appearanceProxy returns NO, so ask the class directly
if ([[UINavigationBar class] instancesRespondToSelector:#selector(setBackIndicatorImage:)])
{
appearanceNavigationBar.backIndicatorImage = [UIImage imageNamed:#"back"];
appearanceNavigationBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:#"back"];
//sets back button color
appearanceNavigationBar.tintColor = [UIColor whiteColor];
}else{
//do ios 6 customization
}
Trying to manipulate the interactivePopGestureRecognizer's delegate will lead to a lot of issues.
I saw this solution http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/ which subclasses UINavigationController. Its a better solution as it handles the case where you swipe before the controller is in place - which causes a crash.
In addition to this I noticed if you do a swipe on the root view controller (after pushing on one, and back again) the UI becomes unresponsive (also same problem in answer above).
So the code in the subclassed UINavigationController should look like so:
#implementation NavigationController
- (void)viewDidLoad {
[super viewDidLoad];
__weak NavigationController *weakSelf = self;
if ([self respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
// Hijack the push method to disable the gesture
if ([self respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.interactivePopGestureRecognizer.enabled = NO;
}
[super pushViewController:viewController animated:animated];
}
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animate {
// Enable the gesture again once the new controller is shown
self.interactivePopGestureRecognizer.enabled = ([self respondsToSelector:#selector(interactivePopGestureRecognizer)] && [self.viewControllers count] > 1);
}
#end
I use
[[UINavigationBar appearance] setBackIndicatorImage:[UIImage imageNamed:#"nav_back.png"]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[UIImage imageNamed:#"nav_back.png"]];
[UIBarButtonItem.appearance setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -64) forBarMetrics:UIBarMetricsDefault];
Here is swift3 version of Nick H247's answer
class NavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
if responds(to: #selector(getter: interactivePopGestureRecognizer)) {
interactivePopGestureRecognizer?.delegate = self
delegate = self
}
}
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
if responds(to: #selector(getter: interactivePopGestureRecognizer)) {
interactivePopGestureRecognizer?.isEnabled = false
}
super.pushViewController(viewController, animated: animated)
}
}
extension NavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
interactivePopGestureRecognizer?.isEnabled = (responds(to: #selector(getter: interactivePopGestureRecognizer)) && viewControllers.count > 1)
}
}
extension NavigationController: UIGestureRecognizerDelegate {}
I also hide the back button, replacing it with a custom leftBarItem.
Removing interactivePopGestureRecognizer delegate after push action worked for me:
[self.navigationController pushViewController:vcToPush animated:YES];
// Enabling iOS 7 screen-edge-pan-gesture for pop action
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
}
navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
This is from http://stuartkhall.com/posts/ios-7-development-tips-tricks-hacks, but it causes several bugs:
Push another viewController into the navigationController when swiping in from the left edge of the screen;
Or, swipe in from the left edge of the screen when the topViewController is popping up from the navigationController;
e.g. When the rootViewController of navigationController is showing, swipe in from the left edge of the screen, and tap something(QUICKLY) to push anotherViewController into the navigationController, then
The rootViewController does not respond any touch event;
The anotherViewController will not be shown;
Swipe from the edge of the screen again, the anotherViewController will be shown;
Tap the custom back button to pop the anotherViewController, crash!
So you must implement UIGestureRecognizerDelegate method in self.navigationController.interactivePopGestureRecognizer.delegate like this:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == navigationController.interactivePopGestureRecognizer) {
return !navigationController.<#TODO: isPushAnimating#> && [navigationController.viewControllers count] > 1;
}
return YES;
}
Try self.navigationController.interactivePopGestureRecognizer.enabled = YES;
I did not write this, but the following blog helped a lot and solved my issues with custom navigation button:
http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/
In summary, he implements a custom UINavigationController that uses the pop gesture delegate. Very clean and portable!
Code:
#interface CBNavigationController : UINavigationController <UINavigationControllerDelegate, UIGestureRecognizerDelegate>
#end
#implementation CBNavigationController
- (void)viewDidLoad
{
__weak CBNavigationController *weakSelf = self;
if ([self respondsToSelector:#selector(interactivePopGestureRecognizer)])
{
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
}
// Hijack the push method to disable the gesture
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if ([self respondsToSelector:#selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = NO;
[super pushViewController:viewController animated:animated];
}
#pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animate
{
// Enable the gesture again once the new controller is shown
if ([self respondsToSelector:#selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = YES;
}
Edit. Added fix for problems when a user tries to swipe left on a root view controller:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self respondsToSelector:#selector(interactivePopGestureRecognizer)] &&
self.topViewController == [self.viewControllers firstObject] &&
gestureRecognizer == self.interactivePopGestureRecognizer) {
return NO;
}
return YES;
}
RootView
override func viewDidAppear(_ animated: Bool) {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
}
ChildView
override func viewDidLoad() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
extension ChildViewController: UIGestureRecognizerDelegate {}
Use this logic to keep enable or disable the swipe gesture..
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animate
{
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)])
{
if (self.navigationController.viewControllers.count > 1)
{
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
else
{
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
}
}
I had a similar problem where I was assigning the current view controller as the delegate for the interactive pop gesture, but would break the gesture on any views pushed, or views underneath the view in the nav stack. The way I solved this was to set the delegate in -viewDidAppear, then set it to nil in -viewWillDisappear. That allowed my other views to work correctly.
Imagine we are using Apple's default master/detail project template, where master is a table view controller and tapping on it will show the detail view controller.
We want to customize the back button that appears in the detail view controller. This is how to customize the image, image color, text, text color, and font of the back button.
To change the image, image color, text color, or font globally, place the following in a location that is called before any of your view controllers are created (e.g. application:didFinishLaunchingWithOptions: is a good place).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UINavigationBar* navigationBarAppearance = [UINavigationBar appearance];
// change the back button, using default tint color
navigationBarAppearance.backIndicatorImage = [UIImage imageNamed:#"back"];
navigationBarAppearance.backIndicatorTransitionMaskImage = [UIImage imageNamed:#"back"];
// change the back button, using the color inside the original image
navigationBarAppearance.backIndicatorImage = [[UIImage imageNamed:#"back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
navigationBarAppearance.backIndicatorTransitionMaskImage = [UIImage imageNamed:#"back"];
// change the tint color of everything in a navigation bar
navigationBarAppearance.tintColor = [UIColor greenColor];
// change the font in all toolbar buttons
NSDictionary *barButtonTitleTextAttributes =
#{
NSFontAttributeName: [UIFont fontWithName:#"HelveticaNeue-Light" size:12.0],
NSForegroundColorAttributeName: [UIColor purpleColor]
};
[[UIBarButtonItem appearance] setTitleTextAttributes:barButtonTitleTextAttributes forState:UIControlStateNormal];
return YES;
}
Note, you can use appearanceWhenContainedIn: to have more control over which view controllers are affected by these changes, but keep in mind that you can't pass [DetailViewController class], because it is contained inside a UINavigationController, not your DetailViewController. This means you will need to subclass UINavigationController if you want more control over what is affected.
To customize the text or the font/color of a specific back button item, you must do so in the MasterViewController (not the DetailViewController!). This seems unintuitive because the button appears on the DetailViewController. However once you understand that the way to customize it is by setting a property on a navigationItem, it begins to make more sense.
- (void)viewDidLoad { // MASTER view controller
[super viewDidLoad];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithTitle:#"Testing"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
NSDictionary *barButtonTitleTextAttributes =
#{
NSFontAttributeName: [UIFont fontWithName:#"HelveticaNeue-Light" size:12.0],
NSForegroundColorAttributeName: [UIColor purpleColor]
};
[buttonItem setTitleTextAttributes:barButtonTitleTextAttributes forState:UIControlStateNormal];
self.navigationItem.backBarButtonItem = buttonItem;
}
Note: attempting to set the titleTextAttributes after setting self.navigationItem.backBarButtonItem doesn't seem to work, so they must be set before you assign the value to this property.
Create a class 'TTNavigationViewController' which is subclass of 'UINavigationController' and make your existing navigation controller of this class either in storyboard/class, Example code in class -
class TTNavigationViewController: UINavigationController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.setNavigationBarHidden(true, animated: false)
// enable slide-back
if self.responds(to: #selector(getter: UINavigationController.interactivePopGestureRecognizer)) {
self.interactivePopGestureRecognizer?.isEnabled = true
self.interactivePopGestureRecognizer?.delegate = self
}
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}}

iOS5 content view controller blocks scroll view on custom container view controller

for backward compatibility to iOS5 I cannot use the Custom View feature of storyboarding.
I have a view controller that has on top a horizontal scroll menu. The scroll view consists of several buttons each of which shows different contents in different ways so I want a child view controller for each content to show.
This image explains better what I'm trying to do.
Following the Apple's developer guide I tried to add the content view controller as child of the main view controller. As soon as the child view controller is presented the scroll view with the buttons menu stopped scrolling. I got stuck on this problem and I don't know why.
Here is the code:
MainViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.menuScrollView.frame = CGRectMake(0, kScrollViewMarginTop, self.view.frame.size.width, kScrollViewHeight);
self.menuScrollView.showsHorizontalScrollIndicator = NO;
self.menuScrollView.pagingEnabled = YES;
self.firstMenuButton.selected = YES;
}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
self.menuScrollView.contentSize = CGSizeMake(kScrollViewContentWidth, kScrollViewHeight);
}
- (IBAction)menuButtonTapped:(id)sender{
UIButton *button = (UIButton *)sender;
switch (button.tag) {
case 0:
if (![self.firstMenuButton isSelected]) {
self.firstMenuButton.selected = YES;
[self.firstMenuButton setBackgroundImage:[UIImage imageNamed:#"firstMenuButton_selected.png"] forState:UIControlStateSelected];
[self deselectButtonsExceptButtonWithTag:button.tag];
//Shows the first content
UIViewController *contentViewController = (UITableViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"firstControllerStoryboardID"];
[self displayContentViewController:contentViewController];
}
break;
default:
break;
}
}
- (void)displayContentViewController:(UIViewController *)viewController{
[self addChildViewController:viewController];
viewController.view.frame = CGRectMake(0, self.menuScrollView.frame.origin.y + self.menuScrollView.frame.size.height + 5.0, 320.0, 200.0);
[self.view addSubview:viewController.view];
[viewController didMoveToParentViewController:self];
}
I tried to achieve it in iOS6 with storyboarding and it works, so I don't know what I'm doing wrong.
Any help is really appreciated
Cheers
I fixed the problem disabling the AutoLayout option from the Storyboard

Display clearColor UIViewController over UIViewController

I have a UIViewController view as a subview/modal on top of another UIViewController view, such as that the subview/modal should be transparent and whatever components is added to the subview should be visible. The problem is that I have is the subview shows black background instead to have clearColor. I'm trying to make UIView as a clearColor not black background. Does anybody know what is wrong with it? Any suggestion appreciated.
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:NO];
SecondViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.opaque = YES;
self.view.backgroundColor = [UIColor clearColor];
}
RESOLVED: I fixed the issues. It is working so well for both of iPhone and iPad. Modal View Controller with no black background just clearColor/transparent. The only thing that I need to change is I replaced UIModalPresentationFullScreen to UIModalPresentationCurrentContext. How simple is that!
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: If you are using a modalPresentationStyle property of navigationController:
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: The bad news is that the above solution doesn't work on iOS 7. The good news is that I fixed the issue for iOS7! I asked somebody for help and here is what he said:
When presenting a view controller modally, iOS removes the view controllers underneath it from the view hierarchy for the duration it is presented. While the view of your modally presented view controller is transparent, there is nothing underneath it except the app window, which is black. iOS 7 introduced a new modal presentation style, UIModalPresentationCustom, that causes iOS not to remove the views underneath the presented view controller. However, in order to use this modal presentation style, you must provide your own transition delegate to handle the presentation and dismiss animations. This is outlined in the 'Custom Transitions Using View Controllers' talk from WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 which also covers how to implement your own transition delegate.
You may see my solution for the above issue in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions
iOS8+
In iOS8+ you can now use the new modalPresentationStyle UIModalPresentationOverCurrentContext to present a view controller with a transparent background:
MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:modalViewController animated:YES completion:nil];
RESOLVED: I fixed the issues. It is working so well for both of iPhone and iPad. Modal View Controller with no black background just clearColor/transparent. The only thing that I need to change is I replaced UIModalPresentationFullScreen to UIModalPresentationCurrentContext. How simple is that!
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: If you are using a modalPresentationStyle property of navigationController:
FirstViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
NOTICE: The bad news is that the above solution doesn't work on iOS 7. The good news is that I fixed the issue for iOS7! I asked somebody for help and here is what he said:
When presenting a view controller modally, iOS removes the view controllers underneath it from the view hierarchy for the duration it is presented. While the view of your modally presented view controller is transparent, there is nothing underneath it except the app window, which is black. iOS 7 introduced a new modal presentation style, UIModalPresentationCustom, that causes iOS not to remove the views underneath the presented view controller. However, in order to use this modal presentation style, you must provide your own transition delegate to handle the presentation and dismiss animations. This is outlined in the 'Custom Transitions Using View Controllers' talk from WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 which also covers how to implement your own transition delegate.
You may see my solution for the above issue in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions
So for purely visual thinkers and storyboard fans, you can do:
1. Presenting View Controller
2. Presented View Controller
Swift 3 & iOS10 solution :
//create view controller
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RoadTripPreviewViewController")
//remove black screen in background
vc.modalPresentationStyle = .overCurrentContext
//add clear color background
vc.view.backgroundColor = UIColor.clear
//present modal
self.present(vc, animated: true, completion: nil)
This is from xCode 7 beta 4 using a control drag segue. Simply set the background of your destination to clear, and set the segue properties in IB as this (nb. Presentation can also be "Over Full Screen"):
I found the easiest way to get it to work on iOS7 and iOS8 is to add set the presentationStyle to UIModalPresentationOverCurrentContext on the modallyPresentedVC (ViewController which you want to present modally) because of iOS8:
[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
and UIModalPresentationCurrentContext on presentingVC (the controller which presents the modallyPresented) because of iOS7:
[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];
Because things are handled differently on iOS7 and iOS8. Of course you don't have to set the navigationController properties if you are not using one. Hope that helps.
Swift2 version :
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
vc.view.backgroundColor = UIColor.clearColor()
vc.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen // orOverCurrentContext to place under navigation
self.presentViewController(vc, animated: true, completion: nil)
Another way (no need to create custom transition and works on iOS 7)
Using Storyboard:
Create the Child View Controller with freedom size, set view width to 500x500 (for example) and add the next method:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 500, 500);
self.view.superview.backgroundColor = [UIColor clearColor];
}
Then create a Modal segue with Form Sheet and test it.
iOS 7 solution with custom segue:
CustomSegue.h
#import <UIKit/UIKit.h>
#interface CustomSegue : UIStoryboardSegue <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
#end
CustomSegue.m
#import "CustomSegue.h"
#implementation CustomSegue
-(void)perform {
UIViewController* destViewController = (UIViewController*)[self destinationViewController];
destViewController.view.backgroundColor = [UIColor clearColor];
[destViewController setTransitioningDelegate:self];
destViewController.modalPresentationStyle = UIModalPresentationCustom;
[[self sourceViewController] presentViewController:[self destinationViewController] animated:YES completion:nil];
}
//===================================================================
// - UIViewControllerAnimatedTransitioning
//===================================================================
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
return 0.25f;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
UIView *inView = [transitionContext containerView];
UIViewController* toVC = (UIViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[inView addSubview:toVC.view];
CGRect screenRect = [[UIScreen mainScreen] bounds];
[toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
[UIView animateWithDuration:0.25f
animations:^{
[toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
}
completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
//===================================================================
// - UIViewControllerTransitioningDelegate
//===================================================================
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
return self;
}
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
//I will fix it later.
// AnimatedTransitioning *controller = [[AnimatedTransitioning alloc]init];
// controller.isPresenting = NO;
// return controller;
return nil;
}
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
return nil;
}
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
return nil;
}
#end
Solution based on hightech code.
For Me this Works:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"MMPushNotificationViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
#ifdef __IPHONE_8_0
if(IS_OS_8_OR_LATER)
{
self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
}
#endif
[self presentViewController:vc animated:NO completion:nil];
MMPushNotificationViewController is the Transparent View controller and also I have made the MMPushNotificationViewController's view color as clearcolor. Now All that I have Done and made my Transparentviewcontroller.
For iOS7
There is now a way to achieve this using the iOS7 custom transitions, this way :
MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];
To create your custom transition, you need 2 things :
A TransitionDelegate object (implementing
<UIViewControllerTransitionDelegate>)
An "AnimatedTransitioning" object
(implementing <UIViewControllerAnimatedTransitioning>)
You can find more informations on custom transitions in this tutorial.
Works Great on iOS7 and iOS8
UIViewController* vc=[[UIViewController alloc]initWithNibName:#"VC" bundle:nil];
vc.view.alpha=0.7;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];
You also can 're-add' the window to the view.
OneViewController *vc = [[OneViewController alloc] init];
if ([self respondsToSelector:#selector(presentViewController:animated:completion:)]) {
[self presentViewController:vc animated:YES completion:nil];
} else {
[self presentModalViewController:vc animated:YES];
}
[[[UIApplication sharedApplication] keyWindow] insertSubview:self.view atIndex:0];
And in this way, presenting can be animated.
For iOS 7 and only by using Interface Builder it can be accomplished by setting the Presentation to "Over Current Context" on all the view controllers involved in the modal presentation. Even for navigation controllers.
For instance, set it on all these view controllers:
NavController -> RootViewController -> ModalViewController
I haven't played around with Storyboard/Interface builder much, but what pops out at me is that you're telling the view to be clear colored (ie. 100% alpha/see-through) and also telling it to be opaque (0% alpha--completely solid). These two things don't seem to mesh. I'd comment out the self.view.opaque = YES; line and see if it works then ;)
Ah, something else I just thought of--its entirely possible that your view controller DOES have the alpha background, but of course the alpha will be showing through to the color of the base window or root view controller of the program, which is by default black. The very base layer of your entire app can't have a transparent background--transparent to what? What's behind it? There has to be something to see THROUGH the transparency. Does that make sense?
Just use "self.modalPresentationStyle = UIModalPresentationCurrentContext;", in presenting view
Will work fine :)

Bottom tabBar hide

hi
In my application i am using TabBar.At first when I call loginControl,I am hiding the tab bar using [login hidesBottomBarWhenPushed=YES]; now if login is a success then I show detailViewController but I do not see the TabBar even after setting hidesBottomBarWhenPushed to NO.
what's the problem... can any one help me??
If you don't need your login view controller anymore you can pop it before push the second. This will do the work but there is strange animation in the back button. It still a solution :)
[navController popViewControllerAnimated:NO];
Edit:
Try this....
loginSuccessController *login = [[loginSuccessController alloc] initWithNibName:#"loginSuccessController" bundle:nil];
[self.navigationController popViewControllerAnimated:NO];
[self.navigationController pushViewController:login animated:YES];
can you try [self setHidesBottomBarWhenPushed:NO]; in your loginsuccesscontroller's viewwillappear or viewdidload
Use this method for hide and show tabbar :)
-(void)makeTabBarHidden:(BOOL)hide
{
UITabBarController *tabBarController = self.tabBarController;
if ( hide == tabBarController.tabBar.hidden ) {
return;
}
UIView *contentView;
if ( [[tabBarController.view.subviews objectAtIndex:0] isKindOfClass:[UITabBar class]] ) {
contentView = [tabBarController.view.subviews objectAtIndex:1];
} else {
contentView = [tabBarController.view.subviews objectAtIndex:0];
}
if (hide) {
contentView.frame = tabBarController.view.bounds;
}
else {
contentView.frame = CGRectMake(tabBarController.view.bounds.origin.x,
tabBarController.view.bounds.origin.y,
tabBarController.view.bounds.size.width,
tabBarController.view.bounds.size.height - tabBarController.tabBar.frame.size.height);
}
tabBarController.tabBar.hidden = hide;
}

iphone loss of tabbar during uimodaltransition

Okay, working on a transition between a view with a tabbar and another view which is to be an information/about view. I have the code to transition from the view with tabbar and to transition back to previous view, but during the transition back I lose the tabbar at the bottom. Not sure exactly how to approach this with the tabbar in the MainWindow.xib
E.g.:
(IBAction)backButtonPressed:(id)sender
{
TablesViewController *tvc = [[TablesViewController alloc] initWithNibName:#"TablesView" bundle:nil];
tvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:tvc animated:YES];
[tvc release];
}
Thanks,
np
Try presenting the modal transition from the containing instance of UITabBarController and not the UIViewController the action was triggered from.
- (IBAction)backButtonPressed:(id)sender
{
TablesViewController *tvc = [[TablesViewController alloc] initWithNibName:#"TablesView" bundle:nil;
tvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.tabBarController presentModalViewController:tvc animated:YES];
[tvc release];
}
I had the exact same problem, did a ugly solution:
- (IBAction)backButtonPressed:(id)sender {
[self.navigationController dismissModalViewControllerAnimated:YES];
}