2

I have an NSDocuments & storyboard app created with the wizard in Xcode 8. In the ViewController Scene I have added a NSTextView. Certain menu items are disabled, such as Bold and Italic.

Looking at the First Responder the actions for bold and italic are not there. Am I supposed to write these methods myself? Is this due to the responder chain not being correctly set up? Why does underline show up but not bold?

Edit: Adding an image to show how I can edit text with the Inspector Bar, but the Format menu does not show the commands I would expect.

Image showing how I can modify text with the Inspector Bar, but not with the menu, apart from Underlining

Henrik
  • 3,908
  • 27
  • 48
  • Sorry what do you mean by "certain menu items are disabled"? Where are these menu items? – rocky Oct 14 '16 at 22:28
  • In the Main Menu of the application, the one that is created with the wizard. The entries are under Format/Font. – Henrik Oct 15 '16 at 05:41
  • Looking at the NSText API it seems there is a method for underlining, whereas I imagine bolding and italicizing text would require changing the font-family. Perhaps that is it. – Henrik Oct 15 '16 at 06:38
  • This appears to be a bug in Xcode; I can't see any reason for this not to work. If you create a new blank project and deselect storyboards it works fine, but if you do the same with storyboards then you get the behaviour you described: some things work, others don't. Perhaps it's because the storyboard adds an `NSViewController`? – TwoStraws Oct 15 '16 at 23:48
  • A little unsure of the issue but have you set the NSTextView to attributed? AFAIK you can only use bold/italics with a plain NSTextView by changing font as you mentioned. – Jahoe Oct 18 '16 at 15:12
  • Adding an image to make it clearer what I am asking about. The NSTextView has Rich Text enabled, and I can modify attributes programmatically and through the Inspector Bar, but the menu entries are greyed out. – Henrik Oct 18 '16 at 19:13

2 Answers2

8

There is a historical (?) reason of this problem. When the main menu was created in a xib file, xib file automatically contained a NSFontManager instance and such menu items like Bold were connected to it. However in a modern storyboard, there is no preset NSFontManager instance.

Well then, you can connect them to a FontManager manually following the following steps.

  1. Create a normal Object instance (blue cube) in the Application scene.
  2. Change class of the Object instance to NSFontManager. enter image description here
  3. Connect the menu items to addFontTrait(_:) action of the fontManager. Likewise, connect "Bigger" and "Smaller" items to modifyFont(_:). enter image description here

You also need to set menuItems' tag, however they are actually already set. Set the correspondent tag also manually only if menuItem's tag is 0.

1024jp
  • 2,058
  • 1
  • 16
  • 25
  • Excellent explanation, even with pictures. Many thanks. – Henrik Oct 20 '16 at 06:21
  • Oh, found it here https://developer.apple.com/library/content/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html#//apple_ref/doc/uid/TP40009459-CH5-SW17 and here https://developer.apple.com/library/content/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html#//apple_ref/doc/uid/TP40009459-CH5-SW11 – Julian F. Weinert Feb 13 '17 at 22:11
0

If you ctrl drag from menu item to first responder, in menu view, you get the same options, just ctrl click. Then you implement whatever function you just connected. If you connect File > New to newDocument and implement in your ViewController

func newDocument(_ sender: Any?){
    print("func newDocument(_ sender: Any? \(String(describing: sender)))")
}

It will get called. First responder lists all the same methods as the added Object with NSFontManager as class. I don't use @IBAction in front of method because I don't connect it.

Peter Ahlberg
  • 1,359
  • 2
  • 24
  • 26