iOS 7 - Fixed status bar, now bottom of PhoneGap app is cut off by 20px - xcode

My PhoneGap application was messed up on iOS 7, like apparently most are at first - the status bar was clear & the text was on top of (overlapping) my app's HTML-based navigation bar. I fixed that by:
In [app name] info.plist:
View controller-based status bar : NO
Status bar style : UIStatusBarStyleLightContent
In MainViewController.m underneath - (void)viewWillAppear:(BOOL)animated is:
self.view.frame = [[UIScreen mainScreen] applicationFrame];
[super viewWillAppear:animated];
NSArray *vComp = [[UIDevice currentDevice].systemVersion
componentsSeparatedByString:#"."];
if ([[vComp objectAtIndex:0] intValue] >= 7) { // iOS 7 or above
CGRect oldBounds = [self.view bounds];
/* Changing the -20 to 0 takes away the black bar
at the top, making the status bar text overlap
my content again... positive 20 of course makes
my content cut off by 20px at the top, so obviously
this is the cause of the problem */
CGRect newBounds = CGRectOffset(oldBounds, 0, -20);
[self.view setBounds:newBounds];
}
I won't bother taking an image of the MainViewController.xib file's settings pane because I'm pretty sure they're made irrelevant by what I've set in info.plist? Let me know if I'm wrong about that.
My app supports rotation as well, in case that matters. And I'm using Cordova 2.1.0.
QUESTION
My HTML code is being cut off by 20px at the bottom because of what I added when trying to get iOS 7's status bar to display properly. If I'm at the bottom of the page in the app & I drag my finger to scroll down further, I can actually see the bottom of my page, but when I lift my finger it's still cut off by 20px (let me know if that makes no sense). What's wrong here? And how do I fix it? In iOS 6 and below, this is NOT an issue - everything is perfect.
Thanks!

https://stackoverflow.com/a/19188984/706751
This is the best solution for people using PhoneGap who experience the iOS 7 Status Bar issue. If other solutions clip your content or don't do well with rotation, this is probably going to work for you!

Related

The bottom of page cannot display in WKWebView

A long web page is rendered in a WKWebView, but a small part of the page on the bottom cannot display even scrolling the page to the bottom.
It seems that the bottom of the page is out of the screen because I can see it when I pull the page up and not releasing my finger.
How can I fix this problem?
I am coming to answer my own question as I have found out the reason that made this issue.
I don't have enough knowledge about Objective-C, so maybe there will be some small mistakes when I describing my answer.
Firstly, there is a default margin at the top of the WKWebView if the property automaticallyAdjustsScrollViewInsets was set to true, and maybe there is a bug of XCode 8.3 (everything was going well when I compiled my code with XCode 8.0), the margin occupied a real part of web page, so the web page can not scroll to its bottom even though I set it to a small size. So set the automaticallyAdjustsScrollViewInsets to false will remove the margin of WKWebView; This is the documentation of this property: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621372-automaticallyadjustsscrollviewin
Then, set the height of WKWebView by the calculation result of that the height of viewport minus the height of the status bar and minus the height of navigation bar.
Pasting my code here:
self.automaticallyAdjustsScrollViewInsets = false;
CGFloat statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake( 0, statusBarHeight + navBarHeight, self.view.bounds.size.width, self.view.bounds.size.height - statusBarHeight - navBarHeight )];

UIScrollView without AutoLayout shows horizontal scroll Indicator in iOS 6 but not in iOS 7

I spent several days trying to see the working UIScrollView horizontal scroll indicator (without AutoLayout) on iOS7 (on iPad). But without success.
Has anyone fixed such bug?
My project is simple and running iOS5 and iOS6 without troubles.
I found out, that on iOS7 height of the scroll indicator image is always zero:
UIImageView * scrollBar = [[scrollView subviews] lastObject];
if (scrollBar != nil)
{
PrintRect(#"FRAME", scrollBar.frame);
PrintRect(#"BOUNDS", scrollBar.bounds);
}
Result for iOS7:
FRAME x:0.000000 y:54.000000 w:338.000000 h:0.000000
BOUNDS x:0.000000 y:0.000000 w:338.000000 h:0.000000
but for iOS6:
FRAME x:0.000000 y:47.000000 w:338.000000 h:7.000000
BOUNDS x:0.000000 y:0.000000 w:338.000000 h:7.000000
So the height scroll bar image on iOS7 is equal to zero.
It's possible to change the height, but only for a quick time because during drugging the height becames zero again.
I was stuck on something similar. I am doing the CS193P course on iTunes and there was this scrollView exercise - Imaginarium. Basically it's just a UIImageView embedded in a UIScrollView. I was having the same problem that the scroll indicators were not being displayed (with Autolayout turned off)
I looked up the header file for UIScrollView in the documentation and there is this property in scrollView called scrollIndicatorInsets:
The distance the scroll indicators are inset from the edge of the scroll view.
#property(nonatomic) UIEdgeInsets scrollIndicatorInsets
It goes on to say that the default value is UIEdgeInsetsZero!! So I created a UIEdgeInset using UIEdgeInsetsMake (see documentation). Then in viewDidLoad I set this UIEdgeInsets to be my scrollView's scrollIndicatorInsets, after which my indicators appeared when I scrolled.
Hope this works for you too.

Subview not appearing where I want it to come out - Xcode

I'm new to XCode and am having trouble getting a subView, when added to the main view, to originate from the bottom whereas the top (which I presume is default).
When I mean top, I don't mean the heir-achy but rather literally top of the screen (where the power button and ear jack of an iphone is).
I have tried to play around with the View -> Origin, and View -> Mode - neither did anything.
I would assume it's the auto-layout but I can't be sure.
Basically, I have a colored mainStoryboard and it [self.view addSubView:[[AnotherView alloc] initWithNibName:#"AnotherView" bundle:nil]];
The AnotherView is just a empty half-sized View.
When it gets added, it keeps appearing from the top. I don't know how to make it come from the bottom.
Do you guys have any insight as to how I might be able to make it come from the bottom?
Thanks ahead of time!
add newView to self.view with the frame
newView.frame=CGRectMake(0,480,320,200);
and after that animate that view by using below animations.
[UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationTransitionCurlUp
animations:^{
newView.frame=CGRectMake(0,0,320,200);
} completion:nil];
Or you can use
presentModalViewController: animated:
method

Modal dismissals do not account for status bar (new iOS 6 issue?)

Didn't have this issue at all until I began adapting my app for iOS 6. Whenever I return from a modal segue (with dismissViewControllerAnimated:completion:), my main view is shifted up by about the status bar's height worth of offset (and is subsequently behind the status bar).
The only workaround I've found is to add:
self.navigationController.view.frame = CGRectMake(0, 20, 320, 460);
self.view.frame = CGRectMake(0, 0, 320, 416);
to my dismissViewControllerAnimated:completion method (those values are for an iPhone < 5 and are just for explanation). But this doesn't really solve the problem, because when I go to present the next modal view controller, the presented view is then shifted up by about the status bar's height worth of offset.
No idea how this issue arose. My suspicion is that, somewhere in the segue, one of the navigation controllers loses track of the status bar's existence (linked to the new status bar, in some way?).
EDIT:
a screenshot of the main view, post-modal dismissal. [Note: 20px whitespace on the bottom]
Resolved the issue. My custom navigationController's supportedInterfaceOrientations was returning UIInterfaceOrientationPortrait, rather than UIInterfaceOrientationMaskPortrait.
Your answer didn't work for me either but I found this solution by Mike Foster that did:
http://fostah.com/ios/2012/09/27/ios6-orientation-handling.html
His steps are:
add the applications supportedInterfaceOrientation and have it return UIInterfaceOrientationMaskAll (or in my case I used AllButUpsideDown)
In your rootViewController implement shouldAutorotate and have it return NO
DO NOT implement supportedInterfaceOrientations in your rootViewController (this seems to be the step that was causing problems with the status bar for me)
In the viewController that should be landscape implement shouldAutorotate to return NO and supportedInterfaceOrientations to return UIInterfaceOrientationMaskLandscape
Hopefully that helps a few other people.
This answer didn't work for me, even though I have the same structure with a custom navigationController as the rootViewController. In my app, I want it in portrait for all VCs except for my modals, which will be UIInterfaceOrientationMaskAll.
What did work was a variation on your workaround, except it will account for iPhone 4 and iPhone 5 screen sizes and the height of the navBar:
[yourParentVC dismissViewControllerAnimated:NO completion:^{
[yourParentVC.view setFrame:CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, [UIScreen mainScreen].applicationFrame.size.height-44)];
//your other completion code
}];
+1 for asking this question...not happy how much work it's been accounting for all the deprecations in iOS 6, so every little bit helps.

iOS6 ScrollBarShouldScrollToTop not firing/ ScrollView Delegate issue

I am adding a dummy ScrollView to my app to detect a user click on the status bar, to performa an event in my program.. I am creating it in the ViewDidLoad:
//Dummy Scroll is for the tap on status bar to work
UIScrollView *dummyScrollView = [[UIScrollView alloc] init];
dummyScrollView.delegate = self;
[[self view ] addSubview:dummyScrollView];
[[self view] sendSubviewToBack:dummyScrollView];
I then implement :
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{
NSLog(#"scrollViewShouldScrollToTop");
.
.
}
Under all previous versions of IOS this has worked beautifully and flawlessly, yet under iOS 6 the scrollViewShouldScrollToTop never gets called. Is this a bug?? The API says this should still be available as part of the delegate in iOS6, yet under iOS6 on both device and simulator it never executes... Anyone have any idea what is going on?
Still no other TableView or ScrollView, but there is a MAPVIEW?? But the MapView doesn't have a shouldScrollToTop that I can find to set to NO.. so I am still beyond confused why this stopped working under iOS 6...
Is there any chance that the UIScrollView you're creating isn't somehow the only UIScrollView in your view hierarchy? It looks like in iOS6, if you have more than a single UIScrollView in your view hierarchy, only one should have scrollsToTop = YES. This is the one that'll have its scrollViewShouldScrollToTop method called.
My problem was similar in that I had a very basic UITableView that would no longer autoscroll to the top when the status bar was tapped. I finally remembered that one of the cells in my tableView uses a UIWebView, and that the cell's webView.scrollView was (correctly, now in iOS6) hijacking the call to scrollViewShouldScrollToTop that, before iOS6, was being made on my tableView.
After setting the tableViewCell's "scrollsToTop = NO", the status bar autoscroll once again worked as it did before. Here's more-or-less how the code looks:
myCustomCellWithAWebView.webView.scrollView.scrollsToTop = NO;
Hope this helps!
On iOS 6, only tap the part above scrollview of status bar can fire scrollsToTop event.
And, that scrollView can't be hidden or 0 alpha.
But it can be covered. or clear background color.
So on iOS 6, you need
dummyScrollView.frame = self.view.bounds;
dummyScrollView.backgroundColor = [UIColor clearColor];

Resources