How do I keep newly added UIWindow on top - ios

There are requirements in my application wherein I need to add the new window for few additional functionalities and I am able to do that successfully. After launching the application I am adding and dismissing windows as per the requirement. But I want to know that how do I keep my current window always on top of other windows if any to avoid conflicts? Are there any ways in iOS where we can keep the presenting window always on top of other ones?

Take a look at makeKeyAndVisible API
func makeKeyAndVisible()
Shows the window and makes it the key window.
This is a convenience method to show the current window and position it in front of all other windows at the same level or lower. If you only want to show the window, change its isHidden property to false.
Also, UIApplication has .windows property, which is an array of visible and hidden windows
var windows: [UIWindow]
You can iterate this array and find a window which you are gonna to set as a key window.
And lastly take a look at .windowLevel UIWindow property, it manages position of the window in the z-axis.
var windowLevel: UIWindow.Level { get set }
Window levels provide a relative grouping of windows along the z-axis. All windows assigned to the same window level appear in front of (or behind) all windows assigned to a different window level. The ordering of windows within a given window level is not guaranteed.
The default value of this property is normal. For a list of other possible window levels, see UIWindow.Level.

The ordering of windows is controlled by UIWindow.windowLevel.
myWindow.windowLevel = .statusBar + 1

Related

SwiftUI: Preload View without displaying

I'd like to "preload" a view (including a SKScene) to gather the bounds of the display area of this scene.
The size information is needed to precompute additional data, the computation should be done in the background while displaying the home screen (different to the screen containing the SKScene).
Q: It it possible to preload a view and if so, how?
Thanks,
J.
OK, found a solution. I switch to the screen directly after application start, gather the needed information and immediately switch to the home screen.
I use the method onAppear() and a global variable as a flag to avoid a second automatic return to the home screen.

Is it possible that an iOS application can have more than one window?

I have been asked this question many times in the interview searched every where didn't get any proper answer.So finally posting this question here.
You may go through this.
Yes, you can have multiple windows. A key window is the one who receives the user input.
Starting with Rob's answer I played around a bit and would like to write down some notes for others trying to get information on this topic:
It is not a problem at all to add another UIWindow. Just create one
and makeKeyAndVisible. Done.
Remove it by making another window
visible, then release the one you don't need anymore.
The window that is "key" receives all the keyboard input.
UIWindow covers everything, even modals, popovers, etc. Brilliant!
UIWindow is always in portrait implicitly. It does not rotate.
You'll have to add a controller to the new window's root controller and let that handle rotation.
(Just like the main window) The window's level determines
how "high" it gets displayed. Set it to UIWindowLevelStatusBar to have it cover everything.
Set its hidden property to NO. A 2nd
UIWindow can be used to bring views on the screen that float on top of everything. Without creating a dummy controller just to embed that in a UIPopoverController.
It can be especially useful for iPhone where there is no popover controller but where you might want to mimic something like it.
And yes, it solved, of course, my problem: if
the app resigns activation, add a cover window over whatever is
currently shown to prevent iOS from taking a screenshot of your
app's current content.
Generally one application require only 1 UIWindow, but still there may be some scenarios where you need to use multiple UIWindow in one application.
For example, you wish to show a view on the top of system AlertViews, or can the default Keyboard.
UIWindows are the special UIViews, for which their display order is controlled by .windowLevel property.
You don't need to add a new UIWindow as a subview of any of view. You can simply create a new UIWindow and call either window setHidden:NO or window makeKeyAndVisible depend on the level, you have given to it.
There are three default window enum levels defined:
UIWindowLevelNormal
UIWindowLevelStatusBar
UIWindowLevelAlert
Of course it can have multiple windows. Just, only one to be displayed at a time, that's the keyWindow. You can have multiple windows stored in array or whatsoever, and make them keyWindow when you want to display them.
And, yeah, read the documentation #Mannopson suggested, it's very useful.

How to continue navigation after changing screens - Skobbler

After a navigation has started, user has an option to switch between screens.
There are two screens with two different maps - one showing navigation and another showing some POIs.
Whenever screen is changed, new delegates are set and [SKRoutingService sharedInstance].mapView is set to the map view of that screen.
Everything works fine, only thing that happens and I want to avoid it - when I go back to the initial screen, the navigation starts from the start again (I was testing this in simulation mode on an iPhone 6 so far).
This happens when I set delegate
[SKRoutingService sharedInstance].routingDelegate = self;
If I don't set the delegate, on return to the main navigation screen, navigation will continue from the position it is intended to, but all the navigation delegate methods will not function.
However, if i set this delegate, navigation will start from the starting point.
How to avoid this ?
Currently, the "navigation" part is shared between all instances of the map - if you start the navigation in one instance, one you switch to another instance then you'll still have the navigation perspective. If you stop it in one view, it will stop across all instances.
What you could do is switch the map do 2D and enable panning - this way you'll still be able to interact with the map (zoom to your POI) and still have the navigation on.
Something similar to what happens in the demo project in the "Car navigation UI" demo when you start panning the map (after starting navigation).
You could really ask this question better. It's hard to understand what the question is about on first reading.
Having said that, it sounds like you're using a 3rd party routing framework, and setting that routingDelegate property has an unintended side-effect (of restarting the navigation). To avoid this, I'd create a new object that should be the routingDelegate all the time. Then this object can notify any other objects that need to know about routing events. This way, you avoid the side effects that are triggered by setting the routingDelegate.

Showing a masked BTProgressHUD without blocking the tab bar?

Is it possible to show a BTProgressHUD with a mask without preventing interaction with the tab bar? In other words, can the mask on a BTProgressHUD be constrained to just the tab's currently shown view controller instead of the full window?
BTProgressHUD.Show(status: "Oh hai", maskType: ProgressHUD.MaskType.Gradient);
I am trying to swap out MTMBProgressHUD for BTProgressHUD (because reasons). Unfortunately, when I show a BTProgressHUD with a mask, it will block the user from selecting another tab while it is shown (something MTMBProgressHUD didn't prevent). I definitely need to block any progression/interaction within the current tab's view controller, but I don't mind if the user switches to another tab instead of waiting for the current tab to complete whatever task is requiring the progress HUD.
Here is the full sample code Gist. It is a bit more complex since it includes the tab bar controller and each tab needs to be able to control their own individual HUDs (when this issue is resolved).
After some discussion on Twitter with the creator of BTProgressHUD, it was determined this isn't possible in the current v1.15 release. He suggesting modifying the source to make this happen. I was able to put together the a working version in just a few lines. (It would still need work to integrate with the BTProgressHUD.Show methods that use a shared instance, but I need discrete HUDs per tabs.)
If you build from this fork, you can then create a BTProgressHUD with a parent view (vs. defaulting to the window) which will restrict the coverage of the overlay mask.
var progressHud = new ProgressHUD(View); // ctor overload requires the forked version
progressHud.Show(status: labelText, maskType: ProgressHUD.MaskType.Gradient);

What is the purpose of UIWindow?

I've always seen references to an app's 'window', and I see that AppDelegates usually have a UIWindow property called 'window'. So I'm just wondering how to perceive this UIWindow object. I see that it's a subclass of UIView, so I guess technically it's a View right? So would it be safe to say it's like the Superview of an entire app? Also, when and why might I ever refer to it? What value does it add?
I know there are a lot of questions in there but just some overall context on UIWindow would be nice.
You might want to check out the About Windows and Views section in the View Programming Guide for iOS.
In iOS, you use windows and views to present your application’s content on the screen. Windows do not have any visible content themselves but provide a basic container for your application’s views. Views define a portion of a window that you want to fill with some content. For example, you might have views that display images, text, shapes, or some combination thereof. You can also use views to organize and manage other views.
Also note that an iOS application usually only has one window. An exception would be, if an app displays content on an external screen.
UIWindow
The presentation of one or more views on a screen is coordinated by UIWindow object. In iOS application usually only has one window. while View multiple. Windows and Views both are used for present your application’s content on the screen. Windows provide a basic container for your application’s views but not have any visible content. The view is a portion of a window where you can fill with some content.For example, you might have views that display images, text.
ProblemStucks
Window is like a topmost UI container for any iOS application. It sits above all of your views and viewControllers.
Ask me why it is needed, And I say it makes the UI structure more clear in terms of view hierarchy and event handling. For example any user event, when not handled by the innermost view, goes up the view hierarchy eventually to the window object if no other view in the hierarchy handles it.
Another example is the rootViewController of a window which handles view-specific details of the application.
There will be mostly one window for an application. But I have worked on an app which used a shared framework for user authentication. And there, we had a separate window specific to that auth framework. Why separate window you ask, and here I go again, there are 2 important use cases,
As I mentioned it was a shared auth framework. Hence different apps could use the same framework for user authentication which uses its own window for login screen etc.
There was a session timeout after which, a login screen had to pop up regardless of what user is currently doing on the screen. This can get really tricky if we don't use a separate window.
I hope you can understand essence of a window after reading these examples.

Resources