Swift: Setting NSStatusBarButton to highlight once NSPopover is displayed - xcode

I have an NSPopover connected to the NSView of a window. Currently I have a NSStatusItem that displays a NSStatusMenu. When you click a certain option in that menu I set the menu to nil and then display the NSPopover. The problem is I want the status bar button to remain highlighted when the NSPopover is displayed, but it only flashes highlight when I click the button to open the NSPopover. I have tried statusItem.button?.highlight(true) to no avail, and it seems changing the button type does not do anything either. Any ideas? Thanks. Also, any way to make the NSView inside the popover or more specifically the text field in the NSView selected once the NSPopover is opened? I have the popover behavior set to transient but it will only close if you click on the popover first, then outside the popover.
#IBOutlet weak var mainMenu: NSMenu!
#IBOutlet weak var popover: NSPopover!
#IBOutlet weak var popoverView: NSView!
#IBOutlet weak var textField: NSTextField!
// init new menu bar item
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
func applicationDidFinishLaunching(aNotification: NSNotification) {
// init menu bar item icon
let icon = NSImage(named: "menuIcon")
icon?.setTemplate(true) // now compatible with "dark mode"
statusItem.image = icon
statusItem.menu = mainMenu
popover.behavior = NSPopoverBehavior.Transient
//statusItem.button?.setButtonType(NSButtonType.OnOffButton)
}
#IBAction func StatusItemClicked(sender: NSButton) {
if !(popover.shown) {
popover.showRelativeToRect(sender.bounds, ofView: statusItem.button!, preferredEdge: NSMinYEdge)
}
else {
popover.close()
}
}
#IBAction func movieRegular(sender: NSMenuItem) {
statusItem.menu = nil // get rid of statusItem menu
statusItem.action = Selector("StatusItemClicked:") // func StatusItemClicked called when button clicked
StatusItemClicked(statusItem.button!) // call it so popover immediately displays first time
}

Related

(Xcode / Swift) How to hide toolbar when scrolling down UIWebView?

I have a UIWebView in my ViewController and a navigation controller embedded in my ViewController. In my navigation controller, I selected "Show Toolbar" and "Hide Bars on Swipe" but the Toolbar doesn't hide. It only works when "Show Navigation Bar" is selected with the Toolbar.
Is there anyway to have the Toolbar hide on swipe when scrolling down the UIWebView?
Thank you in advanced.
You can use UIScrollViewDelegate for that.
Here is example code for hide navigation bar and tool bar with scroll:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var toolBar: UIToolbar!
#IBOutlet weak var webV: UIWebView!
var lastOffsetY :CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
webV.scrollView.delegate = self
let url = "http://apple.com"
let requestURL = NSURL(string:url)
let request = NSURLRequest(URL: requestURL!)
webV.loadRequest(request)
}
//Delegate Methods
func scrollViewWillBeginDragging(scrollView: UIScrollView){
lastOffsetY = scrollView.contentOffset.y
}
func scrollViewWillBeginDecelerating(scrollView: UIScrollView){
let hide = scrollView.contentOffset.y > self.lastOffsetY
self.navigationController?.setNavigationBarHidden(hide, animated: true)
toolBar.hidden = hide
}
}

OS X storyboard: how to show a window programmatically?

I am creating an OS X status bar application.
I am trying to achieve the following:
app starts invisible, with menu bar item
click on menu bar item shows the main window
on deactivate, the window is hidden
So I am trying to programmatically show the main window when the menu item is clicked, but with no success.
My main window has "Hide on deactivate" checked. Once hidden, I cannot make it visible again using code.
Here is the code I have for now, but it doesn't work:
#IBAction func menuClick(sender: AnyObject) {
var mainWindow = NSStoryboard(name: "Main", bundle: nil)?.instantiateInitialController()
mainWindow?.makeKeyAndOrderFront(self)
}
This is how you have to do to show your Windows programmatically:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
let mainWindow = NSWindow(contentRect: NSMakeRect(0, 0, NSScreen.mainScreen()!.frame.width/2, NSScreen.mainScreen()!.frame.height/2), styleMask: NSTitledWindowMask|NSResizableWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask, backing: NSBackingStoreType.Buffered, defer: false)
func createNewWindow(){
mainWindow.title = "Main Window"
mainWindow.opaque = false
mainWindow.center()
mainWindow.hidesOnDeactivate = true
mainWindow.movableByWindowBackground = true
mainWindow.backgroundColor = NSColor(calibratedHue: 0, saturation: 0, brightness: 1, alpha: 1)
mainWindow.makeKeyAndOrderFront(nil)
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
// lets get rid of the main window just closing it as soon as the app launches
NSApplication.sharedApplication().windows.first!.close()
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
#IBAction func menuClick(sender: AnyObject) {
createNewWindow()
}
}
or you can create an optional NSWindow var to store your window before you close it as follow
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var defaultWindow:NSWindow?
func applicationDidFinishLaunching(aNotification: NSNotification) {
// lets get rid of the main window just closing it as soon as the app launches
defaultWindow = NSApplication.sharedApplication().windows.first as? NSWindow
if let defaultWindow = defaultWindow {
defaultWindow.close()
}
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
#IBAction func menuClick(sender: AnyObject) {
if let defaultWindow = defaultWindow {
defaultWindow.makeKeyAndOrderFront(nil)
}
}
}
The makeKeyAndOrderFront method is a NSWindow method, but instantiateInitialController returns the window controller, not its window.
Also, if the window is hidden on deactivate, you wouldn't want to instantiate another copy. Keep a reference to the window and re-show that.
Finally, you may need to bring the app to the front too. Call [NSApp activateIgnoringOtherApps:YES] (or the Swift equivalent).

Calling popover from a menu item crash

I have a toolbar button
#IBOutlet weak var testButton: NSToolbarItem!
The button call a popover and works fine.
But if i try and call the popover from a top menu item i get a crash.
I have amended the location of the popover to appear below the testButton just as it normally would. (commented below)
#IBAction func menuPreviewAndTestAction(sender: AnyObject) {
var returnedHtmlString = checkEverythingAndCreateTheEncodedHtml(testButton)
setEncodedHtmlToPreview(returnedHtmlString)
var thebounds = self.testButton.view?.bounds // so i am givving bounds of button that narmally calls poover
testingPopover.showRelativeToRect(thebounds!, ofView: sender as NSView, preferredEdge: NSMaxYEdge) // crashes
}
Oh dear... I missed changing the ofView, all sorted with :
var thebounds = self.testButton.view?.bounds
var theview = self.testButton.view
testingPopover.showRelativeToRect(thebounds!, ofView: theview! as NSView, preferredEdge: NSMaxYEdge)

Xcode 6 interface builder, cannot link storyboard window to code

I am a relatively new developer working with swift in Xcode 6.1 beta. I am trying to make a simple application that has 2 text fields: 1 for first name, 1 for last name. When the submit button is pressed, a new window opens and displays the full name.
I have successfully gotten the application to work on a single window, with the result appearing in a third non-editable text field.
However, when I add the second view controller to the storyboard for the new window, make it launch when the button is pushed, and drag the result field into it, the application does not work.
I tried re-linking the field to my ViewController.swift (where all my code is), but it does not show up on automatic. When I open it via manual, I cannot link to the file.
original window:
http://i.stack.imgur.com/C0xui.png
new window:
http://i.stack.imgur.com/XdZ2l.png
Viewcontroller.swift:
import Cocoa
class ViewController: NSViewController {
#IBOutlet var window: NSView!
#IBOutlet weak var first: NSTextField!
#IBOutlet weak var last: NSTextField!
#IBOutlet weak var output: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func btn(sender: AnyObject) {
var first = self.first.stringValue
var last = self.last.stringValue
if first.isEmpty {
self.output.stringValue = ""
}
else {
self.output.stringValue = "Hello, \(self.first.stringValue) \(self.last.stringValue)!"
}
}
override var representedObject: AnyObject? {
didSet {
}
}
}
You have to show assistant window in the menu
View > Assistant Editor > Show Assistant Editor

How can I call a function/action when a statusItem is clicked?

I have this code that opens up a popover element at the "sender" location, i.e. the button that was pressed. How can I make this function call when a statusItem is clicked, so that the popover comes down from the status/menu bar?
#IBAction func togglePopover(sender: AnyObject) {
if !(popoverIsOpen) {
myPopover.showRelativeToRect(sender.bounds, ofView: popoverButton, preferredEdge: NSRectEdge(3))
popoverIsOpen = true
}
else {
myPopover.close()
popoverIsOpen = false
}
}
I am currently using NSPopover and NSStatusItem.
edit: The changelog for Xcode 6 beta 4 added NSStatusItem.button and softly deprecated the previous form of calls like NSStatusItem.action, NSStatusItem.title, NSStatusItem.target, etc.
The documentation now reads
NSStatusItem.button
The button that is displayed in the status bar. This is created automatically on the creation of the StatusItem. Behavior customization for the button, such as image, target/action, tooltip, can be set with this property.
I was able to reach an implementation shown below, using the new NSStatusBarButton visual representation of an NSStatusBarItem. In this example, my .xib file has the NSPopover element already connected to a view, which isn't shown here.
#IBOutlet weak var myPopover: NSPopover!
var statusBar: NSStatusItem!
var popoverIsOpen = false
#IBAction func togglePopover(sender: AnyObject) {
if !(popoverIsOpen) {
myPopover.showRelativeToRect(sender.bounds, ofView: statusBar.button, preferredEdge: NSRectEdge(3))
popoverIsOpen = true
}
else {
myPopover.close()
popoverIsOpen = false
}
}
func applicationDidFinishLaunching(aNotification: NSNotification?) {
//initialize menu bar icon
statusBar = NSStatusBar.systemStatusBar().statusItemWithLength(CGFloat(48))
statusBar.button.title = "Your App Title"
statusBar.button.appearsDisabled = false
statusBar.button.action = Selector("togglePopover:")
statusBar.button.target = self
}

Resources