Cocoa APIでスペースに下線を引く

スペース` `をUnicode`\u00a0`に置換すると下線を引いてくれる。

## ベース

説明には以下を利用します。

### プログラム

```main.mm
#import <Cocoa/Cocoa.h>

#define FONT_TYPE @"YuMin-Demibold"

int main () {
    @autoreleasepool {
        // Application
        [NSApplication sharedApplication];
        [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

        // Window
        id window = [
            [NSWindow alloc]
            initWithContentRect:NSMakeRect(0, 0, 300, 120)
            styleMask:NSWindowStyleMaskTitled
            backing:NSBackingStoreBuffered
            defer:NO
        ];
        
        {
            // Name
            [window setTitle: [[NSProcessInfo processInfo] processName]];

            // Position
            [window cascadeTopLeftFromPoint:NSMakePoint(100,100)];
            [window makeKeyAndOrderFront:nil];
        }

        // Text
        {
            // String
            NSString* display_string = @"      Hello, World!      ";

            // Font
            NSTextField* text_field = [
                [NSTextField alloc]
                initWithFrame:NSMakeRect(20, 50, 200, 24)
            ];
            [text_field setFont:[NSFont fontWithName:FONT_TYPE size:18]];
            [text_field setBezeled:NO];
            [text_field setEditable:NO];
            [text_field setSelectable:NO];
            [text_field setDrawsBackground:NO];
            [text_field setTextColor:[NSColor blackColor]];
            [text_field setStringValue:display_string];

            NSMutableAttributedString *attributed_string = [
                [text_field attributedStringValue]
                mutableCopy
            ];
            [
                attributed_string addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle]
                range:NSMakeRange(0, attributed_string.length)
            ];
            [text_field setAttributedStringValue:attributed_string];

            // Set Text Object
            id superview = [window contentView];
            [superview addSubview:text_field];
        }

        // Draw
        [NSApp activateIgnoringOtherApps:YES];
        [NSApp run];

        // Exit
        [NSApp terminate:nil];
    }

    return 0;
}
```

### ビルド

macOS Catalina version 10.15.7のターミナルからビルドします。

```zsh
# Clang version
$ clang --version
Apple clang version 12.0.0 (clang-1200.0.32.27)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

# Build
$ clang ./main.mm -o ./app -fobjc-arc -x objective-c -framework Cocoa
```

### 実行例

ウインドウ上に`Hello, World!`が表示されます。

![スクリーンショット 2021-03-08 8.42.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425840/d7c83bc6-4588-130a-ac70-aaee21232604.png)



## NSString

上記の「実行例」からわかるように、文字列の前後のスペースに下線が引かれていません。

この場合は、`stringByReplacingOccurrencesOfString`を利用して、スペース` `をUnicode`\u00a0`に置換すると線を引いてくれるようになります。

```main.mm.diff
  :
          // Text
          {
              // String
+             NSString* display_string = [
+                 [NSString stringWithCString: "      Hello, World!      " encoding:NSUTF8StringEncoding]
+                 stringByReplacingOccurrencesOfString:@" " withString:@"\u00a0"
+             ];
-             NSString* display_string = @"      Hello, World!      ";

  :
```
![スクリーンショット 2021-03-08 8.28.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425840/1b8e2973-41a3-9085-cdae-4608617772cf.png)