(iOS 7.0.3, Xcode 5.0.1)
I have a second UIWindow in my app used to display a custom magnifier above the status bar. However, once I set the rootViewController of this window (for interface rotation & some other stuff), the main window goes black during the interface rotation animation.
To reproduce: create single view iOS application and add the following to the main UIViewController.
// To #interface:
#property (nonatomic, strong) UIWindow *secondWindow;
// In viewDidLoad:
self.secondWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.secondWindow.rootViewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
self.secondWindow.hidden = NO;
Any help appreciated.
I will add another answer, because I have found a workaround that actually works. Set the window's background color, as well as the view controller's view's background color to a color with an alpha of 0. Do not use clearColor, but rather use something like greenColor] colorWithAlphaComponent:0.0]; It works.
According to an Apple engineer on the dev forums, this is expected due to the window adding a black background to avoid things behind it to be seen (i.e. behind the main window normally). I opened and issue with the Apple bug tracker, #15398141.
Nevertheless, I worked around the issue by hiding the window in willRotateToInterfaceOrientation:duration: and unhiding it in didRotateFromInterfaceOrientation:, which luckily is not a big deal in this case.
This is a known issue, and there are many radars open for it. Best solution so far for me is to add a view as a subview to the window, and manage rotation yourself. This works well.
Make window.opaque = No whose default value is YES. In my case it solved the problem.
Related
I've seen a few questions about status bars and UIWindow, but none of them gave me a solution for this exact problem.
I'd like to make a UIWindow for showing in-app notifications/toasts that appear on top of everything. A UIWindow seems the right way to do this. However, the window affects the status bar. I'd like the status bar to be driven by the original window that contains the rest of the app. Any easy way to do this?
You shouldn't be creating a seperate UIWindow to achieve this. Instead make a Custom View subclassing UIView, do your work in it via code or a Nib. And add it as a subview to your Main Window. [[[UIApplication sharedApplication] keyWindow] addSubview:CustomView];
You can also use bringSubviewToFront to make sure it adds above all other subviews. But it isn't necessary, would be on front in almost all typical scenarios.
This is quite a strange behaviour and I couldn't figure what was wrong out. In iOS7, this code below works as expected but in iOS 8, it has a strange behaviour.
UIView *mainPopupView = [[UIView alloc] initWithFrame:CGRectMake(10, ([UIScreen mainScreen].bounds.size.height-300)/2-50+20, 300, 380)];
mainPopupView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:mainPopupView];
In iOS7, these codes add a white mainPopupView to the present view controller, everything is working properly. But in iOS8, after mainPopupView is presented, a black screen (like an UIView with Black blackgroundColor) appears behind mainPopupView. IMO there has some change about the addSubview: method, I tried various searching on Google but no result. Anyone please explains to me why this happens and how to resolve it?
Thanks in advance.
Try setting the modalPresentationStyle of your PopupViewController instance to UIModalPresentationCustom before presenting it modally.
In case you want to know why this happens, when you present a UIViewController, after the transition animation finishes, the previous view controller is removed from the window hierarchy, since it is not being displayed. When you set the modal presentation style to custom, you are telling the system not to remove the view controller that is presenting. I don't know why it was working pre iOS8.
I have created a UIWindow to show a menu floating over all controllers globally. I want to set the level such that window is always visible plus user can interact with controllers behind it. Window contains a controller which will expand/contract on user tap. See the pictures below:
Currently, I have tried following approach:
UIWindow *statusWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
statusWindow.windowLevel = UIWindowLevelAlert; //Have tried all three
statusWindow.hidden = NO;
[statusWindow addSubview:_gmDemo.view];//my controller's view
[statusWindow bringSubviewToFront:_gmDemo.view];
This code blocks my interaction with controllers behind it. Moreover, when I set it to UIWindowLevelNormal - 1, window is hidden but I can interact with other controllers.
Please tell me correct way to achieve my goal. Thanks.
Note: I have already read this post.
Found solution myself. Problem was UIWindow's frame as well as level. First I set level to UIWindowLevelNormal. Secondly, I have handled window's frame dynamically on menu's button tap. When menu need to be expand/contract, I appropriately increase/decrease size of UIWindow on delegate's call. That's it.
I am trying to create an application with a feature similar to facebook's chat bubbles.
When the user navigates to a certain page (InCallViewController), they can connect to another person via video chat. When they navigate out of this page after connecting, I would like the video view to stay floating on the screen, but allow them to do what ever they want to do in the app.
In order to do this, I have made an InCallViewController class, which will allow the user to connect with the other person. Once connected, the video is displayed in a view. This view is movable (similar to facebook's chat bubbles) and displays the video chat perfectly, however when I exit the page and go to another page (AccountViewController) in the app, I am unable to keep this view on the screen. I have tried many things, including setting this view as a subview in the later pages. However when I do this, the subview is not displayed.
MyAccountView.m
- (void)viewDidLoad
{
[super viewDidLoad];
InCallViewController *inCallViewController = [[InCallViewController alloc] initWithNibName:#"InCallViewController" bundle:nil];
[self.view addSubview:inCallViewController.previewView];
[self.view bringSubviewToFront:inCallViewController.previewView];
(Do some other set up stuff)
}
InCallViewController.h
#interface InCallViewController : UIViewController <UIAlertViewDelegate>
{
CGPoint currentTouch;
NSArray *viewArray;
AVAudioPlayer *audioPlayer;
}
#property (weak, nonatomic) IBOutlet UIView *previewVideoView;
The previewView is a UIView in the InCallViewController class. This is hooked up in the IB, and works perfectly when in the InCallController class. The problem is, it won't show up when adding it as a subview in another class. I am wondering what I am doing wrong, or if there is a better way to keep the "previewView" remaining on the screen after I exit InCallViewController.
Thanks
You should consider implementing a container viewController. Since iOS6 and xcode 4.5 this has been made pretty straightforward.
The containing viewController can be handling your previewViews which are overlayed over whatever viewController is currently contained in it.
You can compare what you want to achieve with what Apple has achieved with a UInavigationController (also a container view controller): it contains viewController that are happily showing their content, but the navigationController makes sure the navigationBar is always present, for all viewControllers, even during animations.
Apple has some good documentation and even a WWDC session on this.
Hacking your way into [[UIApplication sharedApplication] keyWindow] is extremely poor design, and a blatant violation of the MVC pattern. It works, but it is a hack nonetheless and might give you headaches in the future.
You can add previewView to [[UIApplication sharedApplication] keyWindow] as a subview so that it appears on all your views and above each of them.
Hoping somebody can shed some light on this issue...
I'm working on an app that has multiple UIViewControllers each with UITableViews and UIViews in them. I wish to change the background colour for one of the UIViews programmatically. Easy enough to do. I use the RGB values for the colour from a global constants file so that every screen uses the same colour and it can be changed easily for every screen. The issue is that I presently have the code to change the background colour of the view in the viewDidLoad method and I physically see the view change colour. So it loads with whatever it's set to in interface builder and then switches to what I'm setting it to.
Obviously I just want it to appear already set to the colour I'm trying to set it to.
Any thoughts?
More Info
The UIViewController is loaded as a subview into another UIViewController. This parent UIViewController manages a few other UIViewController and allows the user to switch between them. This is how the child UIViewController is loaded:
SomeViewController *vc = [[SomeViewController alloc] initWithNibName:#"SomeViewController" bundle:nil];
self.someViewControllerOutlet = vc;
osvc = nil, [osvc release];
[self.view insertSubview:self.someViewControllerOutlet.view atIndex:0];
Hope this clarifies things.
try using
-(void)awakeFromXib
{
// do your code here
}