【Swift】ボタンをラベルのように見せたい(storyboardから、コードから)

2021/05/06投稿

**※最新版は[haroot.net](https://haroot.net/articles/10)に移動しました。**

# はじめに
Swiftで遊んでるだけの者なので細かいところはわかりません。初心者向けです。

# 動機
ナビゲーションバーの右にラベルを置きたかったのですが、調べた感じだと左右にはボタンしか置けなさそうだったので(違ったら教えてください)、ボタンをラベルのようにしようと思いました。
しかしただボタンを選択不可にするだけだと**デフォルトで色が薄くなってしまうのでこれを直します。**

**※ボタンの宣言やコードとの紐付け(storyboardの場合)は省略します。**

# 環境
macOS Big Sur 11.3
Xcode 12.5
Swift 5.4

# ボタンを選択不可に
<details><summary>storyboardの場合</summary>

storyboardの場合は、ボタンなら Attributes inspector の State   から、ナビゲーションバーのアイテムなら Attributes inspector の Bar Item から Enabled のチェックを外すだけで大丈夫です。
![IMG_3200.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/6e002764-8e14-1a9a-e5bb-ca581e758084.png)
------折りたたみ文ここまで------
</details>
<details><summary>コードで書く場合</summary>

通常の UIButton クラスや UIBarButtonItem クラスには、どちらも`isEnabled`という選択可能かどうかのBool型の変数が用意されているのでこれを`false`(選択不可)にします。`viewDidLoad()`内などで、<div>

```:ViewController.swift
ボタン名.isEnabled = false
```
</div>
と書くだけです。

------折りたたみ文ここまで------
</details>


# ボタンの色を直す
これで選択不可になったのでラベルのようなものにはなりましたが、テキスト色が薄くなっていると思います。次はこれを改善して完全にラベルにしか見えないようにしていきます。

<details><summary>storybardの場合(ボタンのみ)</summary><div>

ボタンだけはstoryboardで色を変えられたので載せますが**あまりお勧めはしません**
(理由は後述)。
![IMG_3202.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/fda74d8d-651e-a72c-777c-e2350226c95a.png)
③での State config を変えると、それぞれの状態の時のボタンの設定を出来ます。
`disabled` にすればボタンが押せな時の装飾を出来ますが、すでに Enable のチェックを外していれば default で `disabled` 状態なので `default` でも `disabled` でも構いません。
<br>
④での text color が default だと、文字が薄くなってしまうので、それ以外に設定します。
**※この時 black color を選ぶと、表示が自動的に default に戻されますが、実際にシミュレータを起動してみるとちゃんと不透明の黒になります。**
storyboardってこういうとこありますよね。。なので非推奨です。。
<br>
------折りたたみ文ここまで------
</div></details>

**※UIBarButtonItem のstoryboardの場合の直し方は見つからなかった(用意されてない？)のでコードで書いていきます**
<br>
<br>
<details><summary>コードで書く場合</summary><div>

UIButton、UIBarButtonItem の細かい装飾にはそれぞれ```setAttributedTitle```、```setTitleTextAttributes```というメソッドを用います。
<br>
**21/05/14追記
UIButtonの場合はボタン色の変更だけであれば、
```ボタン名.setTitleColor(色, for: .disabled)```だけでできますね。**
<br>
<details><summary>UIButton の場合</summary><div>

試しにボタンの```setAttributedTitle```を記述してみます。
![スクリーンショット 2021-05-06 18.27.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/48fcfefa-d40e-40fd-b5f8-e7dd0bf7c4ca.png)
そうすると引数に```NSAttributedString?```と```UIControl.State```を入れろと言われます。

#### NSAttributedString
テキストのフォントのサイズ、種類、色、行間などを指定できるデータ型で、表示するテキスト(```String```)と装飾内容(```[NSAttributedString.Key:Any]```)を指定します。
```[NSAttributedString.Key:Any]```はKeyと値を入れるDictionary型(連想配列)で、文字色や文字サイズを格納するキーを持っています。ここで文字色を指定します。

```title: NSAttributedString?```の欄に、```NSAttributedString(```などと打てば選択肢に```(string: ,attributes: )```が出てくると思うのでそれを選んでください。
![スクリーンショット 2021-05-06 18.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/c593a3d0-95cc-5f41-9469-d6b675623267.png)
```string```は表示するテキストなのでそのまま記入します。
```attributes```は直接書くと非常に見辛いのであらかじめ定数で用意しておくのが一般的だと思います。
![スクリーンショット 2021-05-06 19.05.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/358d6d8a-17ff-eed3-6c52-239950b08924.png)
文字色を指定する場合は```.foregroundColor```を使います。他に使えるキーは適宜調べてみてください。
参考：
・ [NSAttributedString.Key(apple公式)](https://developer.apple.com/documentation/foundation/nsattributedstring/key)
・ [【初心者向け】NSAttributedStringをcustomKeyで自在に操る話【Swift 4】](https://qiita.com/ComeYummy/items/fe2a29b432ca4b6b17b2)

#### UIControl.State
ボタンがどの状態(通常時なのか選択不可時なのか、など)の時にこのメソッドを実行するかを決められます。ここで**選択不可時に**メソッドが実行されるようにします。

```for: UIControl.State```の欄に```.```を入れると選択肢が出ると思うので適宜必要なものを入れてください。
通常時の値は```.normal```、ボタンが使えない時の値は```.disabled```です。
![スクリーンショット 2021-05-06 19.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/3a8919fc-1043-cfdd-1ce8-4e1cff8a1ecf.png)

以上でボタンがラベルのように選択不可かつ不透明になるのが確認出来ると思います。
------折りたたみ文ここまで------
</div></details>
<details><summary>UIBarButtonItem の場合</summary><div>

UIButton の方を見ていただければほぼ同じなのでわかると思います。
まずは試しにバーボタンアイテムの```setTitleTextAttributes```を記述してみます。
![スクリーンショット 2021-05-06 19.31.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/9ed4bdf2-9f6b-939c-719d-9b532f49eb47.png)
すると```[NSAttributedString.Key:Any]?```と```UIControl.State```を打てと言われます。
それぞれの簡単な説明は *UIButton の場合* の方で書いたのでそちらを参照してください([NSAttributedString.Key](#nsattributedstring)、[UIControl.State](#uicontrolstate))。
<br>
UIButtonではボタンのタイトル(```string```)も必要でしたが、UIBarButtonItemでは装飾内容(```[NSAttributedString.Key:Any]```)だけで良いのでテキストはstoryboard上で記入するかコードでアイテム生成時に記入してください。
<br>
UIButton同様、```attributes```を指定し、UIControl.State を```.disabled```にして終わりです。
![スクリーンショット 2021-05-06 19.44.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1156083/cdd0995a-d12d-bd1e-a694-f6936ca92ef3.png)

以上でバーボタンアイテムがラベルのように選択不可かつ不透明になるのが確認出来ると思います。
------折りたたみ文ここまで------
</div></details>
------折りたたみ文ここまで------
</div></details>

# 参考文献
* [NSAttributedString.Key(apple公式)](https://developer.apple.com/documentation/foundation/nsattributedstring/key)
* [【初心者向け】NSAttributedStringをcustomKeyで自在に操る話【Swift 4】](https://qiita.com/ComeYummy/items/fe2a29b432ca4b6b17b2)