How to set NSButton's keyEquivalent to NSDownArrowFunctionKey in Swift - macos

How do I set an NSButton's keyEquivalent (which is a String type) to the down arrow key in Swift? NSDownArrowFunctionKey is an Int.

This page in Apple's documentation addresses this exact issue. The example they provide is written in Objective-C, the Swift equivalent is as follows:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var button: NSButton!
func applicationDidFinishLaunching(aNotification: NSNotification) {
var array = [unichar(NSDownArrowFunctionKey)]
button.keyEquivalent = NSString(characters: array, length: 1)
}
}

Related

NSAttributedStringKey.font not working

I want to add temporary attributes to the text in an NSTextView. It is working for NSAttributedStringKey.foregroundColor but not for NSAttributedStringKey.font. It's also unfortunate that I can't get to the definitive headers to see where NSAttributedStringKey is defined. (I tried cmd-clicking but it's a dead end without the actual definitions).
The code below should work but the font doesn't change
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var textView: NSTextView!
func applicationDidFinishLaunching(_ aNotification: Notification) {
textView.layoutManager?.delegate = self
}
}
extension AppDelegate: NSLayoutManagerDelegate {
func layoutManager(_ layoutManager: NSLayoutManager,
shouldUseTemporaryAttributes attrs: [NSAttributedStringKey : Any] = [:],
forDrawingToScreen toScreen: Bool,
atCharacterIndex charIndex: Int,
effectiveRange effectiveCharRange: NSRangePointer?) -> [NSAttributedStringKey : Any]?
{
var attributes = attrs
if let font = NSFont(name: "Comic Sans MS", size: 14) {
attributes[NSAttributedStringKey.font] = font
}
return attributes
}
}

Passing a value from inputField to NSTextField

I'd like to pass string value from one NSTextField to another NSTextField pressing a button. I used for this for-in loop. I need to pass a value from inputField to visibleText1, then to visibleText2 and then to visibleText3. But it doesn't work.
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var inputField: NSTextField!
#IBOutlet weak var visibleText1: NSTextField!
#IBOutlet weak var visibleText2: NSTextField!
#IBOutlet weak var visibleText3: NSTextField!
func applicationDidFinishLaunching(aNotification: NSNotification) { }
func applicationWillTerminate(aNotification: NSNotification) { }
#IBAction func applyButton(sender: AnyObject) {
for u in (visibleText1.stringValue...visibleText3.stringValue) {
visibleText.stringValue[u] = inputField.stringValue
inputField.stringValue = ""
}
}
}
Xcode gives me an error:
// Type 'ClosedInterval<String>' does not conform to protocol 'SequenceType'
How how to do it right?
No you can't do that because you can't create a range of string values of different text fields.
You could make an array of the three fields and enumerate that:
#IBAction func applyButton(sender: AnyObject) {
for field in [visibleText1, visibleText2, visibleText3] {
field.stringValue = inputField.stringValue
}
inputField.stringValue = ""
}
or with the forEach function
#IBAction func applyButton(sender: AnyObject) {
[visibleText1, visibleText2, visibleText3].forEach {
$0.stringValue = inputField.stringValue
}
inputField.stringValue = ""
}
Resetting the inputField in the repeat loop would always apply an empty string after the first iteration.
There are several things wrong with this, but I will start with what will work:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var inputField: NSTextField!
#IBOutlet weak var visibleText1: NSTextField!
#IBOutlet weak var visibleText2: NSTextField!
#IBOutlet weak var visibleText3: NSTextField!
func applicationDidFinishLaunching(aNotification: NSNotification) { }
func applicationWillTerminate(aNotification: NSNotification) { }
#IBAction func applyButton(sender: AnyObject) {
for u in [visibleText1, visibleText2, visibleText3] {
u.stringValue = inputField.stringValue
}
}
}
So what's wrong with the original?
1) Your (visibleText1.stringValue...visibleText3.stringValue) is of type String ... String, which is not what you intended. You need to have an array of NSTextFields.
2) visibleText.stringValue[u] is not even a thing. There is no variable visibleString, and even if it was an NSTextField - which I think is what you want it to be, it's .stringValue is a String, and not an array.
3) What are you doing setting inputField.stringValue = "" inside the for loop? If your construct worked, only the first field would be set.
4) Not an error, but why are you doing all of this inside NSApplicationDelegate, rather than a viewController?

NSButton color (Vibrant Dark) changes by itself

I have a problem with my buttons:
Buttons A and B look good with any connection (#IBOutlet):
Button B looks bad when is connected:
import Cocoa
class ButtonsC: NSViewController {
#IBOutlet var b: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
}
}
and if I connect the button A, button B looks nice and A looks bad
import Cocoa
class ButtonsC: NSViewController {
#IBOutlet var a: NSButton!
#IBOutlet var b: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
}
}
How can I fix it? or what kind of code in my project may be causing that?

develop mac app swipe from one ViewController to another with Swift(not use storyboard)

i'm the new one develop mac app.When i want to do what i say in title,presentViewController method but with an error said i pass the wrong parameter,but what pass is total the same as what it want.
The error message said "Cannot invoke 'presentViewController' with an argument list of type..."
import Cocoa
class MainViewController: NSViewController {
var uploadViewController: UploadViewController!
#IBOutlet weak var HostFileList: NSScrollView!
#IBOutlet weak var AddFileToHost: NSButton!
#IBOutlet weak var DeleteFileFromHost: NSButton!
#IBOutlet weak var Host: NSTextField!
#IBOutlet weak var Port: NSTextField!
#IBOutlet weak var ConnectServer: NSButton!
#IBOutlet weak var UploadFile: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
}
}
extension MainViewController {
#IBAction func UploadFile(sender: AnyObject) {
var uploadViewController = UploadViewController(nibName: "MasterViewController", bundle: nil)
self.presentViewController(uploadViewController, animator: NSTableViewAnimationOptions.SlideRight)
}
}
On OSX, there is no UINavigationController doing the push/pop stuff and the animation for you!
So you have to do it yourself using ViewAnimations and removeFromSuperview and addSubview to switch out the views manually.
there also a lot of ready made ways for you to do iOS-like stuff on the mac: https://www.google.de/search?client=safari&rls=en&q=uinavigationcontroller+osx&ie=UTF-8&oe=UTF-8&gfe_rd=cr&ei=T3OjVfeqPNfIgATS64G4Dw
The most lightweight at first glance looks to be:
https://github.com/bfolder/BFNavigationController
(note: Im not the author and I dont even know him! :D)

Cannot replace views in swift for OS X

probably I don't understand how views works in swift. I'm trying to replace view in my LoginViewController but nothing is happening.
#IBAction func loginBtn(sender: AnyObject) {
let authViewController = AuthViewController(nibName: "AuthView", bundle: nil)!
let appDelegate = NSApplication.sharedApplication().delegate as AppDelegate
appDelegate.window.contentView.replaceSubview(self.view, with: authViewController.authView)
}
and my AppDelegate.swift
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
#IBOutlet weak var customView: NSView!
#IBOutlet weak var statusMenu: NSMenu!
func applicationDidFinishLaunching(aNotification: NSNotification) {
let loginViewController = LoginViewController(nibName: "LoginView", bundle: nil)!
window.contentView.addSubview(loginViewController.view)
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
I'm not sure but will it help if you tell frame after your replace subview?
let authViewController = AuthViewController(nibName: "AuthView", bundle: nil)!
let appDelegate = NSApplication.sharedApplication().delegate as AppDelegate
appDelegate.window.contentView.replaceSubview(self.view, with: authViewController.authView)
authViewController.view.frame = (appDelegate.window.contentView as! NSView).frame
loginViewController will be deallocated right away as nobody is holding it. Same is true for authViewController
=> VIEWS don't hold their VIEW CONTROLLERS so the views will go away right away
make a member variable to hold on to them

Resources