I want to define by code the color of my status bar, the way I found it was this one but it is deprecated. Does anyone know what the new way of doing this is? This warning is following me in all my codes
This code is working but with the warning
The code for whoever wants:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent
return true
}
By using UIStatusBarManager as mention in the warning, you can not also able to set style.
because statusBarManager is the get only property. Check Here
open var statusBarStyle: UIStatusBarStyle { get }
You have to override the preferredStatusBarStyle
Like this
class ViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
If you want to change the status bar style to all of your view controllers, you can set it inside the Info.plist.
Step 1:
Add View controller-based status bar appearance key and set No value
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
Step 2: Add Status bar style key and set style like Light Content
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
If you want a different style based on controller then,
Step 1:
Add View controller-based status bar appearance key and set Yes value
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
Step 2: override preferredStatusBarStyle within view controller.
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
Here is a good article about How to set status bar style.
You can simply add Appearance key with value Light in your Info.plist
Please check this image for reference
I transplanted a storyboard to another project that uses xibs (yes, the deployment target for the app is 10.9). This storyboard is connected to a NSDocument subclass (available only on 10.10+) which seems to work very good as expected... but the only problem is the main menu that only appear when the window's document goes behind other windows (such Finder ones) and then I put it back in front.
My question is: how can I ensure the main menu get connected to my document?
override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
Swift.print("validateMenuItem")
return super.validateMenuItem(menuItem)
}
override func makeWindowControllers() {
let wc = DocumentWC.loadFromNib()
self.addWindowController(wc!)
}
Not sure what causing the problem (the project it's huge), and probably you can call this a patch instead of a fix:
override func viewDidAppear() {
super.viewDidAppear()
if !self.menufixed {
self.menufixed = true // just to call it once
let win = self.view.window
win?.resignMain()
win?.becomeMain()
win?.orderFrontRegardless()
win?.resignKey()
win?.becomeKey()
win?.orderFrontRegardless()
NSApp.activate(ignoringOtherApps: true)
}
}
P.S. added to the view controller when the view and the window appear.
my app has 04 tabs, i want to write a func to change the background color for the whole screen: status bar, naviation bar, etc.
i want this because when i change color in the func then the whole app will change
below i just change to the top. but too complicated
what i have done is change the status bar text to white
//change text of status bar to white
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
go to the Storyboard, Select the View Controller and in the Editor menu Select Embed in Navigation Controller. Select the Navigation Bar and in the Attribute Inspector set the Bar Tint color to red.
in appDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UINavigationBar.appearance().barStyle = .blackOpaque
return true
}
I am working on a mac application, and I like to make initial window be in maximized state, like when you are pressing green button with plus sign.
I don't want it to be full screen.
An app in its zoomed state is not the same thing as "maximized." The green plus icon indicates zoom, which means "the appropriate size for this content." In some applications that's the visible frame (as Eric D. discusses), but it can be almost anything. Try zooming a Safari window for instance.
Assuming you really want "maximized" and not "zoom", then Eric is on the right track, but it can be done better. First, you should use the window's screen if it has one. Also, you should not animate the window resize during launch (since that can look awkward on launch).
func applicationDidFinishLaunching(aNotification: NSNotification) {
if let screen = window.screen ?? NSScreen.mainScreen() {
window.setFrame(screen.visibleFrame, display: true)
}
}
You may want to consider using a NSWindowController to manage this rather than putting it in the application delegate. In that case, you can put this in windowDidLoad. Window controllers are a pretty common tool in AppKit (as opposed to view controllers, which are not historically as common).
If you actually want zoom behavior, familiarize yourself with the the NSWindowDelegate method windowWillUseStandardFrame(_:defaultFrame:). You shouldn't generally call zoom(_:) directly on launch because that will animate, but whatever logic you do in the delegate should be used to compute your frame. Again, make sure to adjust your frame to live on the window's screen if it has one, rather than the main screen.
Ideally, you really should be honoring the last frame that the user used rather than forcing it to the visible frame. That's called frameAutosave in Cocoa if you want to research that more. A window controller will help you manage that somewhat automatically if you just set a autosave name in Interface Builder. (Though it's slightly complicated by needing to compute the frame on first launch to get the visible frame, so it won't be completely automatic.)
Do give some careful thought before making your default frame be the visible frame in any case. That can be really enormous on large monitors (there are still a lot of 30" Cinema displays out there, but even on a 27" it can be pretty overwhelming). Sometimes that's fine depending on your app, but I often find that it's worth defining a maximum initial size (while allowing the user to make it larger).
You can "zoom" a window to the max available space by using NSScreen's visibleFrame as the target frame. Let's say window is your NSWindow IBOutlet:
if let screen = NSScreen.mainScreen() {
window.setFrame(screen.visibleFrame, display: true, animate: true)
}
For example, in the AppDelegate.swift:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
if let screen = NSScreen.mainScreen() {
window.setFrame(screen.visibleFrame, display: true, animate: true)
}
}
in Swift 4.2:
class ViewController: NSViewController {
override func viewDidAppear() {
super.viewDidAppear()
view.window?.zoom(self) //bespread the screen
//view.window?.toggleFullScreen(self) //fullscreen
}
2020 | SWIFT 5.1:
use extension:
extension NSWindowController {
func maximize() { self.window?.zoom(self) }
}
just call maximize() of NSWindowController instance :)
Swift 5
If anyone's still having issues, trying calling the zoom function the main thread. Worked for me.
DispatchQueue.main.async {
self.view.window?.zoom(self)
}
Hi Guys I really appreciate your help.
I am working on a document based mac application. I put the code you provided in the makeWindowControllers() of Document class and it works like a charm.
Thank you very much. Here is the code I use.
override func makeWindowControllers() {
// Returns the Storyboard that contains your Document window.
let storyboard = NSStoryboard(name: "Main", bundle: nil)
let windowController = storyboard.instantiateControllerWithIdentifier("Document Window Controller") as! NSWindowController
self.addWindowController(windowController)
if let screen = NSScreen.mainScreen() {
windowController.window?.setFrame(screen.visibleFrame, display: true, animate: true)
}
}
this code works well only on single-windowed application, but it's really easy to edit to work with multy-windowed application
usage to maximize and unmaximize window:
TheApp.maximized.toggle()
Source code
public class TheApp {
static var maximized: Bool {
get {
guard let visibleFrame = NSScreen.main?.visibleFrame,
let window = NSApp.mainWindow
else { return false }
return window.frame == visibleFrame
}
set { NSApp.mainWindow?.zoom(newValue) }
}
static var fullscreen: Bool {
get {
guard let screenFrame = NSScreen.main?.frame,
let window = NSApp.mainWindow
else { return false }
return window.frame == screenFrame
} set {
NSApp.mainWindow?.toggleFullScreen(newValue)
}
}
static var mimimized: Bool {
get { NSApp.mainWindow?.isMiniaturized ?? false }
set { NSApp?.mainWindow?.miniaturize(newValue) }
}
}
My product will run fine in debug from xcode to both a simulator and device, but did not run when archived and submitted adhoc. I switched my scheme to run as release, and sure enough, it crashes.
The below portion of code generates an EXC_BAD_ACCESS fault on the var homeNav line. This method is in a custom TabBar Controller. I've also included the app delegate call below, as this is where the tabcontroller is created and displayed.
Tab Controller Call:
//Sets up view on load
override func viewDidLoad() {
super.viewDidLoad()
//Setup and add home view
var homeNav = CMSSNavigationController(navigationBarClass:CMSSNavigationBar.self, toolbarClass:nil)
homeNav.viewControllers.append(CMSSHomeController(nibName:XIBS.VIEW_HOME, bundle:nil))
homeNav.tabBarItem.image = UIImage(named:Images.TAB_HOME)
homeNav.edgesForExtendedLayout = UIRectEdge.None
//Setup and add profile view
var profileNav = CMSSNavigationController(navigationBarClass:CMSSNavigationBar.self, toolbarClass:nil)
profileNav.viewControllers.append(CMSSProfileController(nibName:XIBS.VIEW_PROFILE, bundle:nil))
profileNav.tabBarItem.image = UIImage(named:Images.TAB_PROFILE)
profileNav.edgesForExtendedLayout = UIRectEdge.None
//Set tabs
self.viewControllers = NSArray(objects: homeNav, profileNav)
}
App Delegate call:
//Handles events after launch
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//Setup Google Analytics
GAI.sharedInstance().trackUncaughtExceptions = true
GAI.sharedInstance().dispatchInterval = 20
//TODO: Set logging level for analytics
GAI.sharedInstance().trackerWithTrackingId(GoogleAnalytics.TRACKING_ID)
//Set Window
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
//Create root tab controller
var rootControl = CMSSTabBarController()
self.window?.rootViewController = rootControl
self.window?.makeKeyAndVisible();
return true
}
The code runs fine in release if all UINavigationControllers are declared as CMSSNavigationController() without providing a CMSSNavigationBar.
Why would something like this occur in release, but not debug? I see nowhere that would indicate an object or reference is not allocated correctly here.
The issue was that the toolbar class in the constructor of a UINavigationController cannot be nil. However, the compiler will not complain about this. And, although I cannot say why, the debug will allow it and run fine, but the release will not.
using the line
var homeNav = CMSSNavigationController(navigationBarClass:CMSSNavigationBar.self, toolbarClass:UIToolbar.self)
fixes the issue entirely.