官术网_书友最值得收藏!

Getting user input

So far, we have had very little input from the user. She has launched the app and pressed a button, but the Watch is good for more than just presenting information. While the size of the screen makes some forms of input impractical, and text input via a keyboard must be top of that list, there are still many user input methods, both old and new at our disposal.

WatchKit's text input controller is a very simple way to gather text input (as the name might suggest) using the presentTextInputControllerWithSuggestions method provided by WKInterfaceController. When making this method call, you provide a list of text options from which the user may make a selection (she may also cancel, or choose voice input).

Firstly, we want to modify changeBorderColor() to accept a String argument which will tell it what color the user has selected. Replace the function as it stands with the following:

    func changeBorderColor(colorString: String) {
        let newColor: UIColor
        
        switch colorString {
        case kRed:
            newColor = UIColor.redColor()
        case kPurple:
            newColor = UIColor.purpleColor()
        case kBlue:
            newColor = UIColor.blueColor()
        default:
            return
        }
        
        animateWithDuration(2.5, animations: {
            self.borderGroup.setBackgroundColor(newColor)
        })
    }

The compiler will complain that it knows nothing of kRed, KPurple, and kBlue. These are constants we will create to prevent any typos creeping into our code, such as red instead of Red. Add these constant declarations directly after the import statements at the top of the code:

import WatchKit
import Foundation

let kRed = "Red"
let kPurple = "Purple"
let kBlue = "Blue"

The compiler warnings will now disappear.

Next, remove the code inside buttonTapped(), replacing it with a call to a new method presentColorOptionsToUser() and add the definition for the new method:

func presentColorOptionsToUser() {
    presentTextInputControllerWithSuggestions(
        [kRed, kPurple, kBlue], //1
        allowedInputMode: WKTextInputMode.Plain, //2
        completion:{(results: [AnyObject]?) -> Void in //3
            if let validResults = results, //4
                let resultString = validResults[0] as? String //5
            {
                self.helloButton.setTitle(resultString) 
                self.changeBorderColor(resultString)
            }
    })
}

This is quite an intense chunk of code, so let us take a detailed look at what we are doing.

  • We provide an Array of constant String values that are to be offered to the user.
  • allowedInputMode is set to .Plain, since we have no use for emojis in this particular context (!).
  • We specify the completion closure, which will be called when the user makes a selection (or cancels). This closure takes an optional array of objects, which we have called results; this array will contain the selected String, or nil if no String was selected.
  • We check that results is not nil.
  • We check that first object in the validResults array is indeed a String object and use that the String to set the title of the helloButton, and as the argument to changeBorderColor(colorString: String).

Check that your complete code, including the constant declarations, looks like this:

import WatchKit
import Foundation

let kRed    = "Red"
let kPurple = "Purple"
let kBlue   = "Blue"

class InterfaceController: WKInterfaceController {
    
    @IBOutlet var helloButton: WKInterfaceButton!
    @IBOutlet var borderGroup: WKInterfaceGroup!
    
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
    }
    
    @IBAction func helloButtonTapped(){
        presentColorOptionsToUser()
    }
    
    func presentColorOptionsToUser() {
        presentTextInputControllerWithSuggestions(
            [kRed, kPurple, kBlue],
            allowedInputMode: WKTextInputMode.Plain,
            completion:{(results: [AnyObject]?) -> Void in
                if let validResults = results,
                    let resultString = validResults[0] as? String
                {
                    self.helloButton.setTitle(resultString)
                    self.changeBorderColor(resultString)
                }
        })
    }
    func changeBorderColor(colorString: String) {
        let newColor: UIColor
        
        switch colorString {
        case kRed:
            newColor = UIColor.redColor()
        case kPurple:
            newColor = UIColor.purpleColor()
        case kBlue:
            newColor = UIColor.blueColor()
        default:
            return
        }
        
        animateWithDuration(2.5, animations: {
            self.borderGroup.setBackgroundColor(newColor)
        })
    }
}

When you run the app, tapping the helloButton will now bring up a modal screen offering you the options seen in the screenshot below:

The Cancel button is created automatically by WatchKit. Tapping it will dismiss the modal view, and also return nil to the closure that we provided when calling presentTextInputControllerWithSuggestions, and so our results array will be nil. Our code checks for nil, and thus returns without doing anything.

Tapping the microphone icon will also do nothing; it will not even dismiss the modal view, since Watch Simulator does not handle voice input.

As we can see, the list of text options simply mirrors the array you passed as first argument into presentTextInputControllerWithSuggestions. Tapping one of these will dismiss the modal view and return the appropriate String to the closure, and thus we can use the results value to extract that String.

Did you really read all that before tapping one of the options? Either way, on tapping a color, you will see our button's apparent border (really a Group object) animate to its new color and change its title to reflect the selected text.

A subtle but pleasing animation, I am sure you will agree.

主站蜘蛛池模板: 远安县| 含山县| 江陵县| 湖南省| 旌德县| 开鲁县| 罗田县| 客服| 秭归县| 台中市| 黑龙江省| 蓬溪县| 环江| 依兰县| 临安市| 南丰县| 乌兰县| 阳原县| 沁水县| 东阳市| 盘山县| 佳木斯市| 黄石市| 澄江县| 呈贡县| 安顺市| 昭觉县| 荆州市| 锡林浩特市| 和顺县| 普安县| 桐城市| 辽宁省| 陕西省| 得荣县| 牙克石市| 岢岚县| 岳普湖县| 丰台区| 衡东县| 台安县|