Here is the scenario.
Before launching my app, I make a phone call. Then I open my app, the status bar height has doubled due to call notification. and because of that, the entire UI of my app has been pushed down by additional 20pt. Switching back to phone app and end the call, when I open my app again, the UI gets stuck as just now, except that the green notification bar's gone, leaving an additional 20pt black bar on top.
This does not happen if my app is already launched before I make the call.
I've used [self.window makeKeyAndVisible];
Any idea how to adjust UI properly in this case?
Update:
Here's the code
ADTransitionController *transitionController= [[ADTransitionController alloc] initWithRootViewController:[[MainViewController alloc] init]];
transitionController.wantsFullScreenLayout = YES;
ConfigurationSetupViewController *menuController = [[ConfigurationSetupViewController alloc] init];
REFrostedViewController *frostedViewController = [[REFrostedViewController alloc] initWithContentViewController:transitionController menuViewController:menuController];
frostedViewController.direction = REFrostedViewControllerDirectionLeft;
frostedViewController.liveBlurBackgroundStyle = REFrostedViewControllerLiveBackgroundStyleLight;
if ([GBDeviceInfo deviceDetails].majoriOSVersion < 7) {
frostedViewController.blurRadius = 2;
}
self.window.rootViewController = frostedViewController;
I've drilled down the problem with REFrostedViewController. If I set rootViewController to transitionController, the layout is perfectly aligned.
Update2:
So the fact is.. when a double status bar is present, ADTransitionController will set coordY = 20 and height = 548. REFrostedViewController does the same thing.. causing I have 40 margin on top.. One thing I'm not sure is.. when is the frame of these UIViews being set?
Related
I have a piece of code pointing a UIPopoverController to a menu item in iOS 8/9, it was working in iOS7 and in fact it's in production on the App Store. For some reason, it doesn't show properly when I tried to test the code on iOS 8/9.
For some reason, the iOS framework inserts the black shadow thing about 75% of the screen. It's like it thinks the device is in portrait mode. My app is always in the landscape mode. Portrait is not considered.
When I click on the area outside the dark shadow, I get:
_UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <UIWindow: 0x1355065a0; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x174645520>; layer = <UIWindowLayer: 0x174223920>>
I suspect something is making the framework believes the app is running portrait. The error message above is saying the area outside the dark shadow has no respondent to my clicking action. It's my suspicion, I'm not 100% sure.
and the code:
-(void) showActionControllerByPopover:(UIViewController *)actionController item:(UIBarButtonItem *)item
{
UINavigationController * const navController = [[UINavigationController alloc] initWithRootViewController:actionController];
[navController.navigationBar setBarStyle:UIBarStyleDefault];
[_popController dismissPopoverAnimated:YES];
_popController = [[UIPopoverController alloc] initWithContentViewController:navController];
[_popController setDelegate:self];
[_popController setPopoverContentSize:CGSizeMake(320, 768)];
[_popController presentPopoverFromBarButtonItem:item
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
In my app, a lock screen is used. Sometimes a UIAlertView is shown, now when the user sends the app to the background and brings it in front again, the UIAlertview is shown above the lock screen. Is there a possibility to add a UIViewController's view above everything, i.e. above the UIAlertView?
You should have like this
UIWindow *mySpecialWindowForLockScreen = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
//"Hey iOS Please put this window above all alert view"
mySpecialWindowForLockScreen.windowLevel = UIWindowLevelAlert+100;
UIViewController *lockScreenViewController = [[UIViewController alloc]init];//Lock Screen
lockScreenViewController.view.frame = mySpecialWindowForLockScreen.bounds;
mySpecialWindowForLockScreen.rootViewController = lockScreenViewController;
// In lockScreenViewController view you can add lock screen images and other UI stuff
mySpecialWindowForLockScreen.rootViewController.view.backgroundColor = [UIColor greenColor];
[mySpecialWindowForLockScreen makeKeyAndVisible];
Whenever you want to hide the LockScreen window then simply hide it by setHidden:YES.
There are three kind of UIWindowLevel, the biggest one will be shown above the other window.
So I suggest you use a UIWindow to create your lock screen and let it's window level bigger than UIWindowLevelAlert,
Basically, their values are :
UIWindowLevelNormal = 0.000000;
UIWindowLevel UIWindowLevelAlert = 2000.000000;
UIWindowLevel UIWindowLevelStatusBar = 1000.000000;
so that's why the alert view will show above the other window.have a try.
I currently have a particle view connected to storyboard. The problem that I'm facing is that I'm displaying an alert at the same time I show this view, and the alert is always shown in front of the particle view. Is there a way where I can always place the particle view in front? I'm using a third party alert library titled SIAlertView, so I'm assuming it may be possible.
I've logged the zPosition of the alertView and it's always 0, so I set the zPosition of my particle view's layer to 10, but it is still shown beneath the alert view.
Here's the storyboard hierarchy:
I do not know about SIAlertView but normal UIAlertView is shown via separate window. If you want to overlap it you can not do it by changing zpozition, you have to also use a separate window:
// do not forget to keep strong reference for it somewhere!
UIWindow *notificationWindow;
//your frame here!
notificationWindow = [[UIWindow alloc] initWithFrame: some_cgrect];
notificationWindow.backgroundColor = [UIColor clearColor]; // your color if needed
notificationWindow.userInteractionEnabled = NO; // if needed
// IMPORTANT PART!
notificationWindow.windowLevel = UIWindowLevelAlert + 1;
notificationWindow.rootViewController = [UIViewController new];
notificationWindow.hidden = NO; // This is also important!
UPDATE:
To overlap also a status bar use
notificationWindow.windowLevel = UIWindowLevelStatusBar;
to dismiss UIWindow just invalidate strong pointer to it. Something like:
self.strongPointerToYourWindow = nil;
I am looking at adding AirPlay capabilities to one of my ViewControllers. The View Controller just shows a UIWebView. What I want to do is add a button that will mirror this content to an Apple TV. I know system-wide mirroring can be done, but it doesn't fill up the entire screen, has black bars all around. I have been searching online, but most everything I have found is way back from iOS 5 and out of date. Could someone point me in the direction of a tutorial or drop-in library that would help out? I just need it to mirror the content of just one view to be full-screen on Apple TV.
So far, here is what I have done, but I believe it only creates the second Window, without putting anything on it.
In the AppDelegate, I create a property for it:
#property (nonatomic, retain) UIWindow *secondWindow;
In didFinish method of AppDelegate I run:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(handleScreenDidConnectNotification:)
name:UIScreenDidConnectNotification object:nil];
[center addObserver:self selector:#selector(handleScreenDidDisconnectNotification:)
name:UIScreenDidDisconnectNotification object:nil];
Then in AppDelegate I have:
- (void)handleScreenDidConnectNotification:(NSNotification*)aNotification
{
UIScreen *newScreen = [aNotification object];
CGRect screenBounds = newScreen.bounds;
if (!self.secondWindow)
{
self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
self.secondWindow.screen = newScreen;
// Set the initial UI for the window.
}
}
- (void)handleScreenDidDisconnectNotification:(NSNotification*)aNotification
{
if (self.secondWindow)
{
// Hide and then delete the window.
self.secondWindow.hidden = YES;
self.secondWindow = nil;
}
}
In the viewController in which I would like to allow to mirror the WebView on Apple TV, I have:
- (void)checkForExistingScreenAndInitializeIfPresent
{
if ([[UIScreen screens] count] > 1)
{
// Get the screen object that represents the external display.
UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
// Get the screen's bounds so that you can create a window of the correct size.
CGRect screenBounds = secondScreen.bounds;
appDelegate.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
appDelegate.secondWindow.screen = secondScreen;
// Set up initial content to display...
// Show the window.
appDelegate.secondWindow.hidden = NO;
NSLog(#"YES");
}
}
I got all this from here. However, that's all that it shows, so I'm not sure how to get the content onto that screen.
Depending on what’s going on in your web view, you’ll either have to make a second one pointed at the same page or move your existing one to the new window. Either way, you treat the second window pretty much the same as you do your app’s main window—add views to it and they should show up on the second display.
I assume you've seen it, but this is the only sample project I could find: https://github.com/quellish/AirplayDemo/
Here are some related questions that might be worth reading:
does anyone know how to get started with airplay?
Airplay Mirroring + External UIScreen = fullscreen UIWebView video playback?
iOS AirPlay: my app is only notified of an external display when mirroring is ON?
Good luck!
There are only two options to do Airplay 'mirroring' at the moment: the system-wide monitoring and completely custom mirroring. Since the system-wide mirroring is not a solution for you, you'll have to go down the way you already identified in your code fragments.
As Noah pointed out, this means providing the content for the second screen, the same way as providing it for the internal display. As I understand you, you want to show the same data/website as before on the internal display, but display it differently in the remote view/webview (e.g. different aspect ratio). One way can be having one webview follow the other in a master/slave setup. You'd have to monitor the changes (like user scolling) in the master and propagate them to the slave. A second way could be rendering the original webview contents to a buffer and drawing this buffer in part in a 'dumb' UIView. This would be a bit faster, as the website would not have to be loaded and rendered twice.
I am using IIViewDeckController and I would like to always have the left side controller open and resize the center view so that the layout looks similar to UISplitViewController.
According to the docs:
It is possible to have the viewController always show a side
controller. You do this by setting the maxSize value to any (positive)
nonzero value. This will force the centerview to be always opened,
exposing a side controller permanently. This only works when you have
ONE sidecontroller specified (this means either a left side controller
or a right side controller), because this scenario does not make sense
if you would be able to slide the center view in both directions. When
you have 2 side controllers, this property is ignored.
I have done exactly what it says, but it will not always show the side controller:
PUCNews *news = [[PUCNews alloc] init];
UINavigationController *newsNav = [[UINavigationController alloc] initWithRootViewController:news];
[puc.cachedViewControllers setObject:newsNav forKey:#"news"];
PUCLeftNavigationViewController *leftNav = [[PUCLeftNavigationViewController alloc] init];
IIViewDeckController *deckController = [[IIViewDeckController alloc] initWithCenterViewController:newsNav leftViewController:leftNav];
deckController.openSlideAnimationDuration = 0.20f;
deckController.closeSlideAnimationDuration = 0.20;
deckController.centerhiddenInteractivity = IIViewDeckCenterHiddenNotUserInteractiveWithTapToClose;
deckController.elastic = NO;
if ([Utility isIpad]) {
//deckController.leftSize = 200;
deckController.maxSize = 500;
//deckController.sizeMode = IIViewDeckLedgeSizeMode;
[deckController toggleLeftViewAnimated:NO];
deckController.centerhiddenInteractivity = IIViewDeckCenterHiddenUserInteractive;
deckController.resizesCenterView = YES;
deckController.panningMode = IIViewDeckNoPanning;
}
This also is causing some very strange rotation issues.
How can I always have the left side controller open and resize my center view so that it fits within the rest of the screen?
I've used this,
self.leftController = leftController;
self.leftSize = 700;
[self openLeftViewAnimated:NO];
this works for me because I want a small space in the left size. Probably you need to play with the size afterwards, but this works!
Hope it helps you.
Cheers