SKStoreProductViewController shows the status bar in iOS7 - ios

In iOS7, when a SKStoreProductViewController is presented, it shows the status bar, making it difficult to hit the [Cancel] button.
Can it be disabled?
In my app, UIViewControllerBasedStatusBarAppearance ("View controller-based status bar appearance") is set to YES.

Putting the following code anywhere in the project:
#interface SKStoreProductViewController (StatusBarFixing)
#end
#implementation SKStoreProductViewController (StatusBarFixing)
-(BOOL) prefersStatusBarHidden { return YES; }
#end
... seems to do the trick, even if it is a bit sketchy. However, it would only work if UIViewControllerBasedStatusBarAppearance is set to YES

It seems to me that the status bar is not meant to be shown here. In my opinion, it's best to just hide the status bar and everything will look like it's supposed to.
-(void)showAppInAppstore {
SKStoreProductViewController *spvc = [[SKStoreProductViewController alloc] init];
spvc.delegate = self;
// ... start activity indicator here if you wish
__weak typeof(self) weakSelf = self;
[spvc loadProductWithParameters:#{SKStoreProductParameterITunesItemIdentifier : #(APP_STOREID)}
completionBlock:^(BOOL result, NSError *error) {
// there is no way to stop this task so...
// make sure that user hasn't navigated away from "rate" screen
if(weakSelf != nil && weakSelf.isViewLoaded && weakSelf.view.window != nil) {
// ... stop activity indicator here
if(result == NO || error != nil) {
// handle error if needed
} else {
// Hide status bar
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
// Present store controller
UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController;
[controller presentViewController:spvc animated:YES completion:nil];
}
}
}
];
}
Now make sure that the status bar becomes visible once user is done
-(void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {
[viewController dismissViewControllerAnimated:YES completion:nil];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
}

You can subclass SKStoreProductViewController and control status bar appearance from that point. That's simple and elegant.
SKStoreProductViewControllerWithoutStatusBar.h
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
#interface SKStoreProductViewControllerWithoutStatusBar : SKStoreProductViewController
#end
SKStoreProductViewControllerWithoutStatusBar.m
import "SKStoreProductViewControllerWithoutStatusBar.h"
#interface SKStoreProductViewControllerWithoutStatusBar ()
#property (nonatomic) BOOL wasStatusBarHidden;
#end
#implementation SKStoreProductViewControllerWithoutStatusBar
// Works if UIViewControllerBasedStatusBarAppearance == NO
- (void)viewWillAppear:(BOOL)animated {
self.wasStatusBarHidden = [[UIApplication sharedApplication] isStatusBarHidden];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[[UIApplication sharedApplication] setStatusBarHidden:self.wasStatusBarHidden withAnimation:UIStatusBarAnimationSlide];
[super viewWillDisappear:animated];
}
// Works if UIViewControllerBasedStatusBarAppearance == YES
- (BOOL)prefersStatusBarHidden {
return YES;
}
#end

Related

change one view orientation to landscape

I'm working on a project in which user will watch live channels. But I'm facing a small problem here and I've tried very hard but failed to find any solution. My app will support portrait orientation for all views but last one. Last view will support only landscape orientation. Is it possible?
I've searched and tried following code
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
//
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
//
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);}
Follow this link. Hope you get your answer here.
The link shows how to keep all your views in portrait mode except one view that will be in landscape.
You need to do the following:
1st :
Implement this in all controllers that are fix for portrait:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And implement this for the landscape controllers:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
2nd :
// Fetch the status bar from the app and set its orientation as required.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
// Create an empty view controller, present it modally and remove it directly afterwards
UIViewController *mVC = [[UIViewController alloc] init];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
// Now the device is rotated to the desired orientation. Go from there.
Hope that works.
From iOS6 apple has changed orientation update mechanism. From iOS6 onwards, iOS will report orientation event only to RootController, so all the orientation related decision can only be taken in RootController. Lets say you are using UINavigationController or UITabBarController as window's root controller. In this case you can create sub class of UINavigationController or UITabBarController, override orientation related methods and pass orientation related events to childControllers. Set this custom UINavigationController or UITabBarController object as rootController of your window.
You can override below methods in your custom class.
-(BOOL)shouldAutorotate
{
BOOL shouldRotate = YES;
if(self.viewControllers.count > 0)
shouldRotate = [[self.viewControllers lastObject] shouldAutorotate];
return shouldRotate;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSUInteger supportedInterfaces = UIInterfaceOrientationMaskAll;
if(self.viewControllers.count > 0)
supportedInterfaces = [[self.viewControllers lastObject] supportedInterfaceOrientations];
return supportedInterfaces;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
UIInterfaceOrientation preferredOrientation = UIInterfaceOrientationPortrait;
if(self.viewControllers.count > 0)
preferredOrientation = [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
return preferredOrientation;
}
Use Following approach : In your app delegate .h
#interface PlayWithWSWithLibAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
BOOL flagOrientationAll;
}
#property (assign) BOOL flagOrientationAll;
Add following method in your app delegate .m file
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
//NSLog(#"PlayWithWSWithLibAppDelegate -- supportedInterfaceOrientationsForWindow");
if(flagOrientationAll == YES){
return UIInterfaceOrientationMaskLandscapeRight;
} else {
return UIInterfaceOrientationMaskPortrait ; // your Default orientation for all other view
}
}
Implement following way in your view which you want to rotate in both portrait and landscape both for iPhone device
-(void)viewWillAppear:(BOOL)animated
{
self.tabBarController.delegate = self;
PlayWithWSWithLibAppDelegate *delegate = (PlayWithWSWithLibAppDelegate *) [[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = YES;
}
}
-(void)viewWillDisappear:(BOOL)animated
{
//NSLog(#"viewWillDisappear -- Start");
PlayWithWSWithLibAppDelegate *delegate = (PlayWithWSWithLibAppDelegate *)[[UIApplication sharedApplication] delegate];
delegate.flagOrientationAll = NO;
}

How do I hide the status bar of a pushed view controller in objective c?

I have a signup form that pops up when a button is tapped.
My aim is to hide the status bar when this modal is popped up.
Here is my code:
- (IBAction)tappedJoinButton:(id)sender {
if (![PFUser currentUser]) {
PFSignUpViewController *signUpViewController = [[PFSignUpViewController alloc] init];
[signUpViewController setDelegate:self]; // Set ourselves as the delegate
// Present the sign up view controller
[self presentViewController:signUpViewController animated:YES completion:NULL];
}
}
I have set View controller-based status bar appearance to yes in my plist file. Now I'd like to choose where I hide the status bar. In this situation I'd like to hide it in the signUpViewController that pops up.
I haven't seen any answers on here showing how to hide it in a pushed view controller.
How do I achieve this?
Kind regards
If you want to hide status bar for only one ViewController the do this:
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
- (void)viewWillDisappear:(BOOL)animated{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[super viewWillDisappear:animated];
}
For your case it will be in PFSignUpViewController.
Hope this helps .. :)
Try this code
in viewDidload of PFSignUpViewController
if ([self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)]) {
// iOS 7
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
} else {
// iOS 6
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
paste this function in controller
- (BOOL)prefersStatusBarHidden {
return YES;
}
you lust like ....
if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)
{
[[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
}
Write this in your viewWillAppear...
[[UIApplication sharedApplication] setStatusBarHidden:YES];
Or try This method ....
-(void)navigationController:(UINavigationController *)
navigationController willShowViewController:(UIViewController *)
viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
Add this "View controller-based status bar" appearance in the plist and set NO
[[UIApplication sharedApplication] setStatusBarHidden:YES];

How to hide status bar in UIImagepickercontroller?

I am new to iOS development. I am trying to hide status bar in UIImagePickerController. Whenever I click on "Take photo", status bar appears. It doesn't hide. I want status bar to be hidden only in UIImagePickerController.
Here is my code,
- (IBAction)takePhoto:(UIButton *)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self statusBar:YES];
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:NULL];
}
-(void)statusBar:(BOOL)status
{
[[UIApplication sharedApplication] setStatusBarHidden:status];
}
How to hide the status bar on UIImagePickerController?
This worked fine for me:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
Edit: As of today i just found out that in your info.plist, if you just copy-paste view controller-based status bar appearance there it won't work ... you have to hit enter on a property, and scroll to the last one of them so you will have autocomplete to :view controller-based status bar appearance and an boolean, with no. I tried multiple times but it does not work just copying. Have a nice day.
The solution I found for applications build around :
"View controller-based status bar appearance" set to YES
I did add Category:
//UIImagePickerController+StatusBarHidden.h
#import <UIKit/UIKit.h>
#interface UIImagePickerController (StatusBarHidden)
#end
//UIImagePickerController+StatusBarHidden.h
#import "UIImagePickerController+StatusBarHidden.h"
#implementation UIImagePickerController (StatusBarHidden)
-(BOOL) prefersStatusBarHidden {
return YES;
}
-(UIViewController *) childViewControllerForStatusBarHidden {
return nil;
}
#end
The method childViewControllerForStatusBarHidden is used rarely, but image picker do use it, thats why might cause some troubles
You may also implement UIViewController singleton, with method which returns YES or NO, based on its property.
Then your View controleller implements childViewControllerForStatusBarHidden returning the above singleton.
Changing singleton property automatically change statusbar in app. There also is twin method childViewControllerForStatusBarStyle
However for 2014, iOS8, see this https://stackoverflow.com/a/18960308/294884
I had an issue where in iOS7 my status bar was not being hidden. I hid it programmatically and it still displayed in iOS7, but when ran in iOS6 the status bar would hide appropriately. You have to go to the plist and add the following:
'view controller-based status bar appearance' and set to NO.
If you want the status bar to re-appear in other view controllers and only be hidden on a particular VC, then you set the status bar to hidden YES when the VC loads.
When the VC will disappear you set the status bar hidden back to NO.
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
and when the controller will disappear you add the following to set the status bar so it is no longer hidden and will display on the next View:
-(void)viewWillDisappear:(BOOL)animated{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
setStatusBarHidden:withAnimation: if you want some smooth animation
subclass UIImagePickerController ... mine is V1ImagePickerController ...
.m file looks like this:
#import "V1ImagePickerController.h"
#interface V1ImagePickerController ()
#end
#implementation V1ImagePickerController
- (void)viewDidLoad
{
[super viewDidLoad];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) // iOS7+ only
{
self.edgesForExtendedLayout = UIRectEdgeNone;
[self prefersStatusBarHidden];
[self performSelector:#selector(setNeedsStatusBarAppearanceUpdate)];
}
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (UIViewController *)childViewControllerForStatusBarHidden
{
return nil;
}
#end
the childViewControllerForStatusBarHidden is the key!
If you want to disable the status bar from plist, try this:
Status bar is initially hidden : YES
View controller-based status bar appearance : NO
this is necessary for iOS 7, works for me. I do not know if there are some other techniques for doing this in iOS7. Set these two tags in your info.plist.
Everytime your viewcontroller appears, in viewDidLoad or when image picker controller finishes , use this:
- (void) imagePickerController:(UIImagePickerController *)picker1 didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
.
.
.
.
}
I used Silvertaurus's answer above, but with a little modification to the prefersStatusBarHidden method that I thought was very helpful:
//UIImagePickerController+StatusBarHidden.h
#import <UIKit/UIKit.h>
#interface UIImagePickerController (StatusBarHidden)
#end
//UIImagePickerController+StatusBarHidden.h
#import "UIImagePickerController+StatusBarHidden.h"
#implementation UIImagePickerController (StatusBarHidden)
-(BOOL) prefersStatusBarHidden {
if (self.sourceType==UIImagePickerControllerSourceTypeCamera) {
return YES;
} else {
return NO;
}
}
-(UIViewController *) childViewControllerForStatusBarHidden {
return nil;
}
#end
This keeps the status bar up for the image picker when the camera is not displayed.
Try this
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES];
Also check this discussion.
Please try this.
• Setting a delegate for the UIImagePickerController
• hide the status bar in the delegate's
navigationController:didShowViewController:animated: function.
E.G:
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
You can do it with a category:
#interface UIImagePickerController (HideStatusBar)
#end
#implementation UIImagePickerController (HideStatusBar)
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (UIViewController *)childViewControllerForStatusBarHidden
{
return nil;
}
#end
Source: https://gist.github.com/psobko/9493473
-(IBAction)takePhoto:(UIButton *)sender
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self statusBar:TRUE];
[self presentViewController:picker animated:YES completion:NULL];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[self statusBar:FALSE];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self statusBar:FALSE];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
-(void)statusBar:(BOOL)status
{
[[UIApplication sharedApplication] setStatusBarHidden:status];
}
that might help you to achieve what you want.
Try my answer posted here if you want to keep using ViewController-Based Status Bar Appearance.
In my case I had to use presentViewController to show UIImagePickerViewController (iOS7).
1- Set View controller-based status bar appearance to NO in .plist
2- Create a category for UIImagePickerController and in viewDidLayoutSubviews:
- (void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
3- Added the two following methods to the category:
- (BOOL)prefersStatusBarHidden{
return YES;
}
- (UIViewController *)childViewControllerForStatusBarHidden{
return nil;
}
I hope this will help.
i think i solved this in a pretty simple way without subclassing and using plist.
it only hides for UIImagePickerController.
this example is for bringing up the photo gallary only, but i imagine you can apply it in the same way to anywhere with in uiimagepickercontroller
- (void)showGallary
{
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}];
imgPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
[CATransaction commit];
}

setStatusBarHidden not working

In my UIViewController, I have:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
[self.view sizeToFit];
}
Yet the view looks like this:
I'm sure this code runs. I load the view from a xib. I haven't done anything else to the status bar like change its style. What could be wrong?
Even when I set `application.statusBarHidden = YES" in my app delegate, I see:
In your app's plist, if you have "View controller-based status bar appearance" set to YES, put this code in the view controller in which you hide the status bar:
- (BOOL)prefersStatusBarHidden {
return YES;
}
Else if "View controller-based status bar appearance" is set to NO, call the following whenever you want to hide the status bar.
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
if you want to hide Status Bar in your app , Follow this steps :
Step 1 :
Step 2:
Step 3:
Add to your appDelegate didFinishLaunchingWithOptions function
application.statusBarHidden = YES;
so :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
application.statusBarHidden = YES;
}
That's because iOS 7 has changed the way it deals with the status bar.
Setting UIViewControllerBasedStatusBarAppearance to NO on your app Info.plist should work.
You can show/hide your app status bar using the following code (Works on IOS 7 - IOS 8 and IOS 9):
in your project .h file add this boolean:
BOOL isShowStatus;
And in .m file add this:
//To show the status bar:
-(void)showTheStatusBar
{
isShowStatus = YES;
[self setNeedsStatusBarAppearanceUpdate];
}
//And to hide the status bar:
-(void)hideTheStatusBar
{
isShowStatus = NO;
[self setNeedsStatusBarAppearanceUpdate];
}
- (BOOL)prefersStatusBarHidden {
return !isShowStatus;
}
Simply call it from anywhere, didload for example:
- (void)viewDidLoad
{
[super viewDidLoad];
//To show the status bar:
[self showTheStatusBar];
//Or to hide it:
[self hideTheStatusBar];
}
For me it works fine:
- (BOOL)prefersStatusBarHidden {
return YES;
}
ALWAYS in the root view. If you are doing that in a subview will not work because status bar visibility will be taken from parent view.
Try adding this after you hide the status bar:
[self.view setFrame:[self.view bounds]];
In your appdelegate.m in didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
application.statusBarHidden = YES;
}
When I run your code:

How to hide status bar automatically after load view

guys,
I want to hide the status bar in the code. After loaded view, the status bar will show and it will automatically hide after a while. How to do that?
You want UIApplication's setStatusBarHidden:withAnimation:
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
See the docs.
Haven't tested it and there might be a better way but if you put the following in your load view function:
[self performSelector:#selector(hideNavBar) withObject:nil afterDelay:0.0];
and then have this function
-(void) hideNavBar {
if (self.navigationController.navigationBar.hidden == NO)
{
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
}
You might have to hide the navigation bar in a view animation block. but some combination should work
Check out
link
You could simply do it in you AppDelegate, when applicationDidBecommeActive ("After loaded view").
Set hide status after 400ms, with UIView animation block and calculate your root view controller's navigation bar
// AppDelegate.m
#import "AppDelegate.h"
#import "SomeViewController.h"
#interface AppDelegate ()
#property (nonatomic, strong) SomeViewController *someViewController;
#end
#implementation AppDelegate
- (void)applicationDidBecomeActive:(UIApplication *)application
{
UINavigationBar *navBar = self.someViewController.navigationController.navigationBar;
if (![[UIApplication sharedApplication] isStatusBarHidden]) {
[[UIApplication sharedApplication] setStatusBarHidden:YES
withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.4
animations:^{
navBar.frame = CGRectMake(navBar.frame.origin.x, 0, navBar.frame.size.width, navBar.frame.size.height);
} completion:nil];
}
}
#end
that's it, "After loaded view (didBecomeActive), the status bar will show and it will automatically hide after a while (400ms)"
You have to select your project and select Hide during application launch inside the header General, section Deployment Info like this:
And inside the info.plist set the View controller-based status bar to NO:

Resources