Category: User Interface

November 29th, 2017 by admin

On many Apple products when you type in a password incorrectly, the text field appears to “shake” back and forth as if telling you, “Nope. You entered a password incorrectly.” To create this shaking effect on a text field, you need to create an extension.

Extensions let you define new methods for manipulating an object. Since a text field is an object, created from the UITextField class, it’s possible to extend this UiTextField class with a custom shaking function.

To see how this works, create a Single View App iOS project and add a text field and a button on the user interface. Create an IBOutlet for the text field like this:

@IBOutlet weak var textField: UITextField!

Then create an IBAction method for the button like this:

    @IBAction func checkPassword(_ sender: UIButton) {
        if textField.text == password {
            textField.text = "ACCESS GRANTED"
        } else {
            textField.shake()
        }
    }

This simple project works by displaying a text field and a button. If you type a password correctly in the text field, then the text field displays the text “ACCESS GRANTED”. However, if you type an incorrect password, then the text field runs a shake function. To create this shake function, you need to create an extension at the bottom of the ViewController.swift file past the last curly bracket like this:

extension UITextField {
    func shake() {
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.05
        animation.repeatCount = 5
        animation.autoreverses = true
        animation.fromValue = CGPoint(x: self.center.x - 4.0, y: self.center.y)
        animation.toValue = CGPoint(x: self.center.x + 4.0, y: self.center.y)
        layer.add(animation, forKey: "position")
    }
}

This shake function defines an animation that lasts 0.05 seconds, repeats itself 5 times, and moves the text field 4.0 pixels to the left and 4.0 pixels to the right, which creates the “shaking” visual effect.

Your complete ViewController.swift file should look like this:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    let password = "password"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func checkPassword(_ sender: UIButton) {
        if textField.text == password {
            textField.text = "ACCESS GRANTED"
        } else {
            textField.shake()
        }
    }
    
}

extension UITextField {
    func shake() {
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.05
        animation.repeatCount = 5
        animation.autoreverses = true
        animation.fromValue = CGPoint(x: self.center.x - 4.0, y: self.center.y)
        animation.toValue = CGPoint(x: self.center.x + 4.0, y: self.center.y)
        layer.add(animation, forKey: "position")
    }
}

When you run this app in the Simulator, type the word “password” in the text field and you’ll see the words “ACCESS GRANTED” in the text field. If you type anything other than “password” in the text field, the text field will shake back and forth.

By using extensions, you’ve extended the text field to make the shake() method available to the text field. Any time you want to modify a user interface item, use an extension to modify that object’s behavior.

Posted in Algorithms, User Interface

May 4th, 2017 by admin

When you create a macOS project that uses storyboards, each window is called a view, which has a border. Two ways to modify the border of a view is to change its width and change its color.

To change the view’s border width, you need to use the borderWidth property like this:

self.view.layer?.borderWidth = 5

One way to make it easy to change the width of a border is to use a slider. Then create an IBOutlet for that slider along with an IBAction method like this:

@IBOutlet weak var borderSlider: NSSlider!

@IBAction func sliderChanged(_ sender: NSSlider) {
        self.view.layer?.borderWidth = CGFloat(borderSlider.intValue)
}

To change the view’s border color, you need to use the borderColor property like this:

self.view.layer?.borderColor = NSColor.blue.cgColor

The simplest way to change the border color is through a color well. Just create an IBOutlet and an IBAction method for that color well, in addition to overriding the changeColor function like this:

@IBOutlet weak var colorWell: NSColorWell!

@IBAction func pickColor(_ sender: NSColorWell) {
        colorWell.activate(true)
        colorWell.action = #selector(changeColor)
}
    
override func changeColor(_ sender: Any?) {
        self.view.layer?.borderColor = colorWell.color.cgColor
}

If you have a slider and a color well on your view, users can drag the slider back and forth to modify the border width and click on the color well to choose a different color for that border. You can download a sample program that shows how this works:

BorderSetting sample program.

Posted in Algorithms, User Interface

April 20th, 2017 by admin

The TouchBar replaces the largely useless row of function keys on some of the MacBook Pro laptops. Since Apple recently updated their iWork office suite to take advantage of the TouchBar, it’s likely that the TouchBar will eventually find its way to other Macintosh models including on an external keyboard for the iMac, mac mini, and Mac Pro.

Since the TouchBar will likely be another user interface accessory, it’s important to know how to write macOS programs that offer a TouchBar. If you’re writing macOS programs and don’t have a TouchBar, you can simply use the TouchBar Simulator.

To use the TouchBar Simulator, open Xcode and choose Window > Show Touch Bar (or press Shift+Command+5). If you run any macOS program that supports the TouchBar, you’ll be able to see how those programs offer shortcuts on the simulated TouchBar.

To add TouchBar support to your macOS programs, click on your Main.storyboard file to display your user interface, then open the Object Library window. In the search field, type touchbar and the Object Library will display all the touch bar items you can add, including NSTouchBar, which is the touch bar itself.

Drag the NSTouchBar from the object Library over the Window Controller in your storyboard. The TouchBar will appear directly beneath this Window Controller.

Now you can drag other TouchBar items from the Object Library window on to the TouchBar such as NSTouchBar Slider or NSTouchBar Button. For this example, drag NSTouchBar Color Picker on to the TouchBar.

Now the TouchBar needs its own class file, so choose File > New > File. Click macOS and then click the Cocoa Class icon. Then click the Next button. A new window appears, asking for your class name and subclass.

The name can be anything you want, such as TouchClass. What’s far more important is that the Subclass is NSWindowController.

Click the Next button and then click the Create button. This adds the TouchClass.swift file to the Navigator pane, Now the next step is to link this TouchClass.swift file to the TouchBar.

Click on Main.storyboard and click on the blue icon that appears in the top, middle of the Window Controller where you added the TouchBar. Choose View > Utilities > Show Identity Inspector. Click in the Class popup menu and choose TouchClass (or whatever name you chose for your class file).

Once you’ve connected the TouchBar to a class file, choose View > Assistant Editor > Show Assistant Editor. You want the assistant editor to display the TouchClass.swift file, but you may need to manually choose this TouchClass.swift file to make it appear in the assistant editor.

When opening the TouchClass.swift file, you may see an error message. Just let Xcode correct this error and it will likely add a @available line such as the following:

@available(OSX 10.12.2, *)

Now with the TouchBar displaying a color picker, control-drag from the TouchBar color picker to the  top of the TouchClass.swift file.

When a popup menu appears, choose the following:

  • Connection: Outlet
  • Name: colorIcon
  • Type: NSColorPickerTouchBar

This creates an IBOutlet to the color picker on the TouchBar with code that looks like this:

@IBOutlet weak var colorIcon: NSColorPickerTouchBarItem!

Modify the windowDidLoad functions follows:

    override func windowDidLoad() {
        super.windowDidLoad()
        
        colorIcon.isEnabled = true
        colorIcon.target = self
        colorIcon.action = #selector(colorPicked)

    }

When a popup menu appears, choose the following:

  • Connection: Action
  • Name: colorPicked
  • Type: NSColorPickerTouchBar

This creates an IBAction method. Now edit this IBAction method with one line of code like this:

    @IBAction func colorPicked(_ sender: NSColorPickerTouchBarItem) {
        window?.backgroundColor = colorIcon.color as NSColor
    }

Choose Product > Run and you should see your program’s user interface, but probably not any sign of the simulated TouchBar. To display the TouchBar, go back into Xcode and choose Window > Show Touch Bar (or press Shift+Command+5).

Go back to your TouchBar program and you should now see the simulated TouchBar visible. Click on the color picker on the TouchBar to display a range of colors. Each time you click on a color, the background of the window should display that color.

TouchBar Example

Posted in Algorithms, User Interface

April 16th, 2017 by admin

If you’re creating a macOS program, you may want to display a dialog box on the screen to alert the user of something, such as an error message of some kind. The simplest way to create a dialog is to use the NSAlert class like this:

        let myAlert = NSAlert()
        myAlert.messageText = "Message text"
        myAlert.informativeText = "Informative text"
        myAlert.runModal()

If you create a push button on a window and store the above code in an IBAction method for This code creates a simple dialog that looks like this:

The messageText property defines the bold text and the informativeText property defines the text that appears underneath.

As an alternative to displaying a modal dialog, you can also display a sheet instead by using this code:

        let myAlert = NSAlert()
        myAlert.messageText = "Message text"
        myAlert.informativeText = "Informative text"
        myAlert.beginSheetModal(for: self.view.window!, completionHandler: nil)

This creates a sheet like this:

A simple dialog that displays a message is fine. When the user wants to dismiss the dialog, he or she can just click the OK button. However in many cases, you may want to add up to three buttons on a dialog with custom text. To do that, you need to use the addButton method like this:

        myAlert.addButton(withTitle: "Save")
        myAlert.addButton(withTitle: "Delete")
        myAlert.addButton(withTitle: "Cancel")

To determine which button the user clicked, you need to use a switch statement. If you created a modal dialog using the runModal() method, your switch statement might look like this:

        switch myAlert.runModal() {
            case NSAlertFirstButtonReturn: print ("Save")
            case NSAlertSecondButtonReturn: print ("Delete")
            case NSAlertThirdButtonReturn: print ("Cancel")
            default: print ("Nothing")
        }

So if you placed a push button on a window, and created an IBAction method to display a dialog by clicking this push button, your entire code might look like this:

    @IBAction func showAlert(_ sender: NSButton) {
        let myAlert = NSAlert()
        myAlert.messageText = "Message text"
        myAlert.informativeText = "Informative text"
        
        myAlert.addButton(withTitle: "Save")
        myAlert.addButton(withTitle: "Delete")
        myAlert.addButton(withTitle: "Cancel")
        
        switch myAlert.runModal() {
            case NSAlertFirstButtonReturn: print ("Save")
            case NSAlertSecondButtonReturn: print ("Delete")
            case NSAlertThirdButtonReturn: print ("Cancel")
            default: print ("Nothing")
        }
    }

To determine which button the user clicked if you created a sheet, your switch statement would look slightly differently:

        myAlert.beginSheetModal(for: self.view.window!, completionHandler: { (returnCode) -> Void in
            switch returnCode {
                case NSAlertFirstButtonReturn: print ("Save")
                case NSAlertSecondButtonReturn: print ("Delete")
                case NSAlertThirdButtonReturn: print ("Cancel")
                default: print ("Nothing")
            }
        })

If you created a push button on a window with an IBAction method to open a sheet, your entire IBAction method code might look like this:

@IBAction func showAlert(_ sender: NSButton) {
        let myAlert = NSAlert()
        myAlert.messageText = "Message text"
        myAlert.informativeText = "Informative text"
        
        myAlert.addButton(withTitle: "Save")
        myAlert.addButton(withTitle: "Delete")
        myAlert.addButton(withTitle: "Cancel")

        myAlert.beginSheetModal(for: self.view.window!, completionHandler: { (returnCode) -> Void in
            switch returnCode {
                case NSAlertFirstButtonReturn: print ("Save")
                case NSAlertSecondButtonReturn: print ("Delete")
                case NSAlertThirdButtonReturn: print ("Cancel")
                default: print ("Nothing")
            }
        })

    }

By using the NSAlert class, you an easily create and display dialogs as modal dialog boxes or as a sheet. You an also customize the number of buttons (up to three) and retrieve which button the user clicked on.

Posted in Algorithms, macOS, User Interface

March 26th, 2017 by admin

One type of controller you can add to a macOS project storyboard is a page controller. The main purpose of the page controller is to display the contents of two or more view controllers that users can swipe left and right like swiping through pages in an e-book.

To use a page controller, you need to add a page controller to a storyboard. Next, you need to create additional view controllers that are completely separate from the storyboard (not connected to any existing storyboard scenes through segues). These view controllers will only appear within the page controller. You must then give each of these view controllers a unique identifier (name).

To create a unique identifier for each view controller, click on that view controller and then choose View > Utilities > Show Identity Inspector to open the Identity Inspector for that view controller.

Click the blue icon in the top, middle of the view controller window. Then click in the Storyboard ID text field in the Identity Inspector pane and type a descriptive name.

This name can be anything you ant but you’ll refer to this descriptive name later when making the view controller appear inside the page controller.

Next, you must create a Swift class file for your page controller. To do this you’ll need to create a new class file and make sure its subclass is NSPageController. The name can be arbitrary but you’ll need to remember this name when connecting it to the page controller in the storyboard.

Now click on the page controller in your storyboard, click on the blue icon in the top, middle of the Page Controller, and choose View > Utilities > Show Identity Inspector. The Identity Inspector pane appears. Click in the Class popup menu and choose the name you created for the page controller class file.

At this point, you’ve created a page controller and two or more view controllers that are separate from he rest of your storyboard. Now you’ll need to start writing Swift code.

Start by defining your page controller Swift file as an NSPageControllerDelegate. So if you named your Swift class file to control the page control as MyPageController, you’ll need to edit this file so the class heading looks like this:

class MyPageController: NSPageController, NSPageControllerDelegate {

Underneath this class file heading, create an array. The number of items in this array must be equal to the number of view controllers you want to display inside the page controller. So if you wanted to display three view controllers in the page controller, you might create an array with three arbitrarily named items like this:

var myViewArray = ["one", "two", "three"]

Inside the viewDidLoad function, you need to define the class file as its own delegate, set the arrangedObjects property to the name of your array, and define a transitionStyle as either:

  • .horizontalStrip
  • .stackBook
  • .stackHistory
    override func viewDidLoad() {
        super.viewDidLoad()

        delegate = self
        self.arrangedObjects = myViewArray
        self.transitionStyle = .horizontalStrip
    }

The transitionStyle property defines how the page controller displays the view controllers.

Now you need to add three additional functions to this page controller Swift class file:

   func pageController(_ pageController: NSPageController, viewControllerForIdentifier identifier: String) -> NSViewController {
        
        switch identifier {
        case "one":
            return NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "Page01") as! NSViewController
        case "two":
            return NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "Page02") as! NSViewController
        case "three":
            return NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "Page03") as! NSViewController
        default:
            return self.storyboard?.instantiateController(withIdentifier: identifier) as! NSViewController
        }
    }
    
    func pageController(_ pageController: NSPageController, identifierFor object: Any) -> String {
        return String(describing: object)
        
    }
    
    func pageControllerDidEndLiveTransition(_ pageController: NSPageController) {
        self.completeTransition()
    }

The first function uses a switch statement that uses the strings (“one”, “two”, and “three”) that are stored in the array, which is stored in the page controller’s arrangedObjects property. This switch statement links each array item to a specific view controller in the storyboard.

Remember, these three view controllers are not connected to any part of the storyboard but can be retrieved using their Storyboard ID.

The second function displays the view controller in the page controller.

The third function ends the transition when the user swipes left or right.

The complete page controller Swift class file contents should look like this:

import Cocoa

class MyPageController: NSPageController, NSPageControllerDelegate {
    
    var myViewArray = ["one", "two", "three"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        delegate = self
        self.arrangedObjects = myViewArray
        self.transitionStyle = .stackBook
    }
    
    func pageController(_ pageController: NSPageController, viewControllerForIdentifier identifier: String) -> NSViewController {
        
        switch identifier {
        case "one":
            return NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "Page01") as! NSViewController
        case "two":
            return NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "Page02") as! NSViewController
        case "three":
            return NSStoryboard(name: "Main", bundle:nil).instantiateController(withIdentifier: "Page03") as! NSViewController
        default:
            return self.storyboard?.instantiateController(withIdentifier: identifier) as! NSViewController
        }
    }
    
    func pageController(_ pageController: NSPageController, identifierFor object: Any) -> String {
        return String(describing: object)
        
    }
    
    func pageControllerDidEndLiveTransition(_ pageController: NSPageController) {
        self.completeTransition()
    }
    
}
Sample NSPageController example

Posted in macOS, User Interface

March 6th, 2017 by admin

If you want to make an item on the user interface appear to fade away and reappear again, you can use something called the animator() method. Essentially all you have to do is create an IBOutlet for a user interface item (such as a button or label) and then apply the animator() method along with defining the alphaValue property to 0 (completely invisible) or 1 (completely visible).

Of course, if you assign a user interface item’s alphaValue property to 0, it will suddenly disappear, so that’s why you need to create a delay effect using the following code:

NSAnimationContext.current().duration = 3

This simply tells code to delay the animator() action by three seconds (or whatever number you assign to the duration property.

Create a simply macOS project using storyboards and place a label and a push button anywhere on the view. Create IBOutlet for the label like this:

@IBOutlet weak var lblMessage: NSTextField!

Now create an IBAction method for the push button (call it AnimateMe) and fill it with Swift code such as:

    @IBAction func animateMe(_ sender: NSButton) {     
        if lblMessage.animator().alphaValue == 1 {
            NSAnimationContext.current().duration = 3
            lblMessage.animator().alphaValue = 0
        } else {
            NSAnimationContext.current().duration = 3
            lblMessage.animator().alphaValue = 1
        }
    }

This code simply checks what the alphaValue of the label might be. If its value is 1 (completely visible), then it slowly fades the label away in three seconds and sets its alphaValue property to 0. This creates a gradual fade out visual effect.

If the label’s alphaValue property is already 0, then the above Swift code takes three seconds to slowly set the alphaValue to 1, which creates a fade in visual effect.

Obviously there’s more to animation using the animator() method but this can get you started in seeing how simple it can be to create animation in a macOS program.

Posted in Algorithms, macOS, User Interface

February 24th, 2017 by admin

A Split View Controller can display two or more views side by side. Separating the views is a divider that the user can drag back and forth to widen shrink a view. There are two ways to change the appearance of this divider:

  • Choose a style
  • Choose a color

The divider style can appear as Thick, Thin, or Pane Splitter. Strangely, the Thick and Pane Splitter styles look nearly identical with the only difference being that you can change the color of a Thick divider but not a Pane Splitter divider.

To choose a divider style, open the Document Outline pane and click on the Split View.

Next, open the Attributes Inspector pane by choosing View > Utilities > Show Attributes Inspector. In the Style popup menu, choose the style you want for your divider.

Changing the color of the divider is a bit stranger and trickier. Open the Document Outline pane and click on Split View. Now open the Identity Inspector pane by choosing View > Utilities > Show Identity Inspector.

Look for the User Defined Runtime Attributes category and click on the + icon. This creates a generic row of data listing keyPath, Boolean, and a check mark.

Double-click on keyPath and change this text to dividerColor and press Return.

Under the Type column, click the popup menu and change Boolean to Color.

Under the Value category, click the popup menu that appears there and choose a color.

If you chose a Thick or Thin style (not a Pane Splitter) and defined a color, run your project and you should see your chosen divider style and color appear in the split view.

 

 

Posted in macOS, User Interface

January 28th, 2017 by admin

When you create a macOS Cocoa Application project, you project starts out with a Window Controller and a View Controller.

The Window Controller defines the actual window that appears on the screen but the View Controller defines the contents that appears inside the Window Controller. You need to place user interface items like buttons and text fields on the View Controller so when your program runs, these user interface items appear on the View Controller, which appears inside the Window Controller.

A View Controller represents a simple window, but Xcode offers several other types of view controllers such as a Page Controller, a Split View Controller, and a Tab View Controller. If you want any of these other types of controllers to appear inside the Window Controller, you need to follow two steps:

  • Delete the currently existing View Controller
  • Add the new controller you want to put in its place such as a Tab View Controller or Page Controller

To delete the existing View Controller, you need to delete both the View Controller in the storyboard and the ViewController.swift file. To delete the ViewController.swift file in the Navigator pane, just right-click over it and when a popup menu appears, choose Delete.

To delete the View Controller from the storyboard, select the View Controller by clicking the Show Document Outline icon and then clicking on View Controller Scene in the Document Outline. Then press Backspace or choose Edit > Delete.

Initially the contents of the Window Controller displayed View Controller but now it should display No Content View Controller.

Now drag another controller from the Object Library window to the storyboard such as Page Controller or Vertical Split Controller. This will place a new controller on the storyboard but now you’ll need to connect this newly added controller to appear inside the Window Controller.

Click on the blue icon that appears in the top, middle of the Window Controller. Hold down the Control key and Control-drag over the new controller you just added.

Release the Control key and the left mouse/trackpad button. A popup menu appears.

Choose window content. Your newly added controller now displays a connecting arrow to show that it appears inside the existing Window Controller.

Posted in macOS, User Interface, Xcode

January 7th, 2017 by admin

At one time, the only way to create user interfaces for macOS or iOS programs was to use .xib files. Nowadays, the only way to create user interfaces for iOS apps is to use storyboard files. To create macOS programs, you still have the option of using either .xib or .storyboard files, but since storyboards are used for iOS programming, you might as well start using storyboards for creating macOS user interfaces as well.

When you use storyboards to create a macOS project, you can create segues between scenes (windows) in your storyboard. For example, create a macOS Cocoa Application project that uses storyboards and you’ll wind up with a single window controller that looks like this:

The top box is the window controller and the bottom box is the view controller that appears inside the window controller. (Yes, I know this sounds confusing because it is.)

You need to add user interface items like buttons and text fields in the bottom box (the view controller). That view controller box is also connected to a class file called ViewController.swift so you can write IBOutlets and IBAction methods to control any user interface items you add to the view controller box.

If you want to add another scene to a storyboard, you have to drag a view controller from the Object Library on to the storyboard. Xcode offers several different types of view controllers such as the plain View Controller or the more sophisticated Tab View Controller or Horizontal/Vertical Split View Controller, which offers more than just a single window to display on the screen. Xcode offers the following types of view controllers you can add to a storyboard.

Whatever type of new controller you want to add to a storyboard doesn’t matter but whatever type you add, you must create a Swift Cocoa Class file to control that view controller. So if you add a View Controller, you must create a Cocoa Class file that’s a subclass of NSViewController. If you add a Page Controller, you must create a Cocoa Class file that’s a subclass of NSPageController.

After you’ve added a view controller to a storyboard, you need to choose File > New > File to create a macOS Cocoa Class as shown below.

After clicking the Next button in the bottom right corner, you need to give your class file a name (which can be anything, but more importantly, you must choose a subclass as shown below.

Once you’ve chosen the proper subclass to represent your newly added view controller in the storyboard, the final step is to connect that class file to the view controller in the storyboard.

To do this, click on your storyboard file in the Navigator pane and then click on the blue icon at the top, middle of the newly added view controller to select it. Choose View > Utilities > Show Identity Inspector. In the Class popup menu, choose the name of the class file you just created.

It’s important to remember that every view controller (scene) in a storyboard needs to be connected to a class file. When you add various user interface items to a view controller (scene), you can open the Assistant Editor and control-drag to create IBOutlets and IBAction methods in the class file connected to that view controller.

Posted in macOS, User Interface, Xcode

December 21st, 2016 by admin

If you’re creating a macOS program using storyboards, you may need to know the size of a window. To get this information, you just need to follow two steps:

  • Create an IBOutlet that represents your window. This IBOutlet should be of the type NSView
  • Use the frame.width and frame.height properties to get the width and height of the window defined by your IBOutlet

To create an IBOutlet for a window, just opens he Assistant Editor, move the mouse pointer over the window, and Control-drag to the Swift class file linked to your window such as ViewController.swift. Then release the Control key and the left mouse button to create an IBOutlet.

You can use any name for your IBOutlet, but whatever name you choose will now represent your window such as:

@IBOutlet var myWindow: NSView!

Assuming you named your window IBOutlet myWindow, you’ll be able to access the frame.width and frame.height properties like this:

myWindow.frame.height
myWindow.frame.width

If you put the following two lines of code in the viewDidLoad function that runs as soon as a window appears, you’ll see the defined width and height of the window.

print ("Window height = \(myWindow.frame.height)")
print ("Window width = \(myWindow.frame.width)")

Posted in Algorithms, User Interface

HTML Snippets Powered By : XYZScripts.com