Uiwindow? Does Not Have Member Named Bounds

UIWindow? does not have member named bounds

The declaration of the window property in the UIApplicationDelegate protocol
changed from

optional var window: UIWindow! { get set } // beta 4

to

optional var window: UIWindow? { get set } // beta 5

which means that it is an optional property yielding an optional UIWindow:

println(UIApplication.sharedApplication().delegate.window)
// Optional(Optional(<UIWindow: 0x7f9a71717fd0; frame = (0 0; 320 568); ... >))

So you have to unwrap it twice:

let bounds = UIApplication.sharedApplication().delegate.window!!.bounds

or, if you want to check for the possibility that the application delegate has
no window property, or it is set to nil:

if let bounds = UIApplication.sharedApplication().delegate.window??.bounds {

} else {
// report error
}

Update: With Xcode 6.3, the delegate property is now also
defined as an optional, so the code would now be

let bounds = UIApplication.sharedApplication().delegate!.window!!.bounds

or

if let bounds = UIApplication.sharedApplication().delegate?.window??.bounds {

} else {
// report error
}

See also Why is main window of type double optional? for more solutions.

UIWindow?' does not have a member named 'rootViewController'

Try this, you have to initialize before access it :

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {

// declaration of products like in your above code
....

window = UIWindow(frame: UIScreen.mainScreen().bounds)
let navController = window!.rootViewController as! UINavigationController

let tableViewController = navController.viewControllers[0] as! MainTableViewController
tableViewController.products = products

return true
}

I hope this help you.

UIWindow not showing over content in iOS 13

I was experiencing the same problems while upgrading my code for iOS 13 scenes pattern. With parts of your second code snippet I managed to fix everything so my windows are appearing again. I was doing the same as you except for the last line. Try removing viewController.present(...). Here's my code:

let windowScene = UIApplication.shared
.connectedScenes
.filter { $0.activationState == .foregroundActive }
.first
if let windowScene = windowScene as? UIWindowScene {
popupWindow = UIWindow(windowScene: windowScene)
}

Then I present it like you do:

popupWindow?.frame = UIScreen.main.bounds
popupWindow?.backgroundColor = .clear
popupWindow?.windowLevel = UIWindow.Level.statusBar + 1
popupWindow?.rootViewController = self as? UIViewController
popupWindow?.makeKeyAndVisible()

Anyway, I personally think that the problem is in viewController.present(...), because you show a window with that controller and immediately present some 'self', so it depends on what 'self' really is.

Also worth mentioning that I store a reference to the window you're moving from inside my controller. If this is still useless for you I can only show my small repo that uses this code. Have a look inside AnyPopupController.swift and Popup.swift files.

Hope that helps, @SirOz

UIWindow not filling screen for new devices?

Try to add "Launch screen interface file base name" (UILaunchStoryboardName) to your Info.plist

It seems that the presence of this key tells the system that you natively support new device types and size classes, so your window can fill all available area.

How to set UIWindow property in Swift

The problem is that self.window is an Optional. You first have to "unwrap" it. You also need to use clipsToBounds not setClipsToBounds.:

if let window = self.window {
window.clipsToBounds = true
window.frame = CGRect(x: 0, y: 20, width: window.frame.size.width, height: window.frame.size.height);
window.bounds = CGRect(x: 0, y: 0, width: window.frame.size.width, height: window.frame.size.height);
}

Note: I also updated CGRectMake to the preferred Swift way of creating CGRect using the CGRect initializer instead of the global CGRectMake function.

UIWindow orientation issues (two UIWindows and landscape mode)

The system will only handle rotation of your keyWindow. If you have other windows you'll have to handle rotation yourself.

I also think that modal controllers is the way to go. But if you really want to handle rotations take a look at how other "custom windows" libraries handle rotation. Alert views are a great example:

https://github.com/search?o=desc&q=uialertview&s=stars&type=Repositories&utf8=✓

Why is main window of type double optional?

@matt has the details, but there is a (somewhat horrible, somewhat awesome) workaround. (See edit below, though)

let window = app.delegate?.window??.`self`()

I will leave the understanding of this line of code as an exercise for the reader.

OK, I lie, let's break it down.

app.delegate?.window

OK, so far so good. At this point we have the UIWindow?? that is giving us a headache (and I believe is a bug in Swift disconnect between Swift and Cocoa). We want to collapse it twice. We can do that with optional chaining (?.), but that unwraps and rewraps, so we're back where we started from. You can double-optional-chain, though, with ??. which is bizarre, but works.

That's great, but ?? isn't a legal suffix operator. You have to actually chain to something. Well, we want to chain back to itself (i.e. "identity"). The NSObject protocol gives us an identity method: self.

self is a method on NSObject, but it's also a reserved word in Swift, so the syntax for it is `self`()

And so we get our madness above. Do with it as you will.

Note that since ??. works, you don't technically need this. You can just accept that view is UIWindow?? and use ??. on it like view??.frame. It's a little noisy, but probably doesn't create any real problems for the few places it should be needed.

(*) I used to think of this as a bug in Swift, but it's not fixable directly by optional chaining. The problem is that there is no optional chaining past window. So I'm not sure where the right place to fix it is. Swift could allow a postfix-? to mean "flatten" without requiring chaining, but that feels odd. I guess the right operator would be interrobang delegate?.window‽ :D I'm sure that wouldn't cause any confusion.

EDIT:

Joseph Lord pointed out the better solution (which is very similar to techniques I've been using to avoid trivial if-let, but hadn't thought of this way before):

let window = app.delegate?.window ?? nil // UIWindow?

I agree with him that this is the right answer.

Swift Optional of Optional

The property window of UIApplicationDelegate protocol is declared like this:

optional var window: UIWindow? { get set }

That means that it is an optional property (in the sense that "the class implementing the UIApplicationDelegate protocol is not requested to implement/have this property", like when you have @optional in Objective-C), and that property is of optional type Optional<UIWindow> (or UIWindow?).

That's why you have the double-optional type in the end, because that window property may or may not be implemented in realDelegate, and if it is, it will be itself of type Optional<UIWindow>/UIWindow?.


So basically what you want is to return the window property of your realAppDelegate… only if that realAppDelegate decided to declare that property itself (which it isn't requires to do, as it's optional var).

  • If the realAppDelegate did not implement window itself, you probably intend to return a nil UIWindow? as a result.
  • If your realAppDelegate did actually implement the window property, then you need to return it as is (wether this implementation returns an actual UIWindow or a nil one).

The easiest way to do that is to use the nil-coalescing operator ?? in Swift. a ?? b meaning that "if a is non-nil, then return a, but if a is nil, return b" (where if a is of type T?, then the whole expression is expected to return an object of type T, where in your case T is the type UIWindow?).

var window: UIWindow? {
get {
// If realAppDelegate.window (of type UIWindow??) is not implemented
// then return nil. Otherwise, return its value (of type UIWindow?)
return realAppDelegate.window ?? nil
// That code is equivalent (but more concise) to this kind of code:
// if let w = realAppDelegate.window { return w } else return nil
}
...
}

To implement the setter, that's another problem. According to this SO answer, directly accessing to the setter of an optional property of a protocol doesn't seem to be possible. But you can imagine a hack to workaround this, by declaring another protocol that makes this window property requirement mandatory, then try to cast to it in the setter:

@objc protocol UIApplicationDelegateWithWindow : UIApplicationDelegate {
var window: UIWindow? { get set }
}

class AppDelegateWrapper : UIApplicationDelegate {
...
var window: UIWindow? {
get {
return realAppDelegate.window ?? nil
}
set {
if let realAppDelWithWindow = realAppDelegate as? UIApplicationDelegateWithWindow
{
// Cast succeeded, so the 'window' property exists and is now accessible
realAppDelWithWindow.window = newValue
}
}
}
...
}


Related Topics



Leave a reply



Submit