16

How to change the label appearing at the top left corner that says "Cancel" when I open a modal view... I would like it to be a button with an image.

Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
Hugo Alonso
  • 6,684
  • 2
  • 34
  • 65

4 Answers4

30

The label Cancel is the default 'title' of a modally presented WKInterfaceController, which appears on the Apple Watch status bar.

Replacing the title with an image

It is not possible to hide the status bar, nor is it possible to display an image in the status bar, neither as part of this link nor to replace this link.

Options to set modal view title

You can however set the title to a new string value. For instance, you might well want to replace Cancel with Close. There are four ways that you can set this title, which are outlined below. Ensure you read the Note at the bottom as likely only Option 1 will be acceptable in most circumstances.

  1. You can set the title of the modally presented WKInterfaceController in Interface Builder. Simply set the Title attribute in the Attributes Inspector. Only a single static title can be set this way for each WKInterfaceController, of course, although it can be changed dynamically at runtime using any of the mechanisms outlined above.

  2. You can set the title in the init method for the modally presented WKInterfaceController:

    override init () {
        super.init ()        
        self.setTitle("Close")
    }
    
  3. You can set the title directly in the awakeWithContext method of the modally presented WKInterfaceController:

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        self.setTitle("Close")
    }
    
  4. You can pass the title to the modally presented WKInterfaceController using the context variable. In interface builder, set the identifier in the Attributes Inspector of the controller to be presented modally. (In this example, it was set to "modalController".) You then present the controller by passing the desired title as the Context:

    self.presentControllerWithName("modalController", context: "Close")
    

    Then, in the modally presented controller:

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)                
        self.setTitle(context as? String)
    }
    

Note:

The current 'intended behaviour' of WatchKit almost certainly means that only the first option will be seen as acceptable in most use cases. This is because currently, for the other three options you will initially see the default title for the view as it loads, which will then be replaced with the text you set using setTitle. awakeWithContext runs by design after the view has loaded, but even using setTitle in init does not avoid the initial display of the default title.

The first option outlined above replaces Cancel with a new default title for the view. If you combine a custom Title in Interface builder with any of Options 2-4 below, you see exactly the same symptom (initial title then being replaced with your setTitle), just with a different initial title.

Duncan Babbage
  • 19,972
  • 4
  • 56
  • 93
  • 2
    Hi @Duncan Babbage, is it possible to disable the "cancel button" user interaction? The reason I want to do this is because I have 3 interface controllers, the 1st presents (modal segue) the 2nd, and the 2nd presents ( (modal segue) the 3rd. However I want to disable the "cancel button" for the 3rd view controller and use a WKInterfaceButton to go back to the 1st controller. – user1872384 Feb 13 '15 at 06:39
  • 1
    I'm at the same situation. I don't want users to cancel the current page and go back one page but want them to go all the way back to the root. I think what we can currently do is keep an internal variable in context object and keep the page transition state there. If you detect transition one page back, then call popToRootController. – Shu Suzuki Apr 05 '15 at 08:47
  • 1
    I'm also in same page. Did you guys got any solution for disable cancel button? @user1872384 – simbesi.com Jun 04 '15 at 07:49
  • @Duncan Babbage It's interesting I found my label is "abbrechen" instead of "Cancel", but I didn't change the language to German ("abbrechen" is German for "Cancel"). Here is my related question post - http://stackoverflow.com/questions/41457733/the-label-cancel-from-modal-segue-in-apple-watch-showing-wrong-text-abbrech – allenlinli Jan 04 '17 at 06:46
6

It is possible to remove/hide the title. Just copy ' ' into the title field in the storyboard. It is not ASCII space. It is the Chinese space. (Though you can't see the title, you still can tap the top left corner to close the model view.)

Then you can create a new button to close the model view with the code: [self dismissController];

Vince Yuan
  • 10,533
  • 3
  • 32
  • 27
2

I looked at the "Presenting Interface Controllers Modally" section of the WatchKit programming guide, which said:

The top-left corner of a modal interface displays the interface controller’s title string. When the user taps that string, WatchKit dismisses the modal interface. Set the title string to reflect the meaning of dismissing the modal interface. For example, when displaying information, you might set the string to Done or Close. If you do not specify a title for your interface controller, WatchKit displays the string Cancel by default.

And about that "Cancel" bit, the WKInterfaceController documentation for presentControllerWithName:context::

The title of the modal interface is set to the string Cancel unless the presented interface controller explicitly changes it using the setTitle: method.

seems to indicate your only choice at this time is another string, not an image.

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
0

A working, albeit limited, method to put in image in the title is to use an emoji character. As of Xcode 7.1 the simulator seems to suffer from a bug and displays wrong characters there, but it works perfectly fine on the device.

setTitle("Hello world! ")
Krzysztof Szafranek
  • 758
  • 1
  • 6
  • 10