adjustsFontSizeToFitWidth
というプロパティがあるので、それをtrueにすると、
自動調整が効きます。
adjustsfontsizetofitwidthしてみよう
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(x: view.center.x - 50, y: view.center.y - 7.5, width: 100, height: 15))
lable.text = "12345678901234567891"
label.font = .systemFont(ofSize: 15)
view.addSubview(label)
幅100ptのUILabelに、フォントサイズ15で20文字表示してみましょう。

表示できませんね。
10文字が限界で、11文字以上のテキストは10文字目が…で省略されます。
label.adjustsFontSizeToFitWidth = true
これを入れてみましょう。

表示できました。やったね!
IBでやる場合
ここからできます。

IBだと最小値を絶対に指定させる仕様っぽいです。
UIButton
UIButtonも文字部分はUILabelを使っているので、同じようにadjustsfontsizetofitwidthが使えます。
注意点1.最小値を設定しないとどこまでも小さくなる
ここからadjustsfontsizetofitwidth使う際の罠をいくつか書いていきます。
上記のラベルのテキストをもっと長くしてみます。
label.text = "Too long string, it's very very long string. Extraordinary long string we could not display it"
するとこうなります。

拡大するとちゃんと表示できてるんですが、ここまで小さいとさすがに表示してる意味がないですね。
Appleのドキュメントには、
If you change it to true, be sure that you also set an appropriate minimum font scale by modifying the minimumScaleFactor property.
(抄訳)もしadjustsfontsizetofitwidthをtrueにしたなら、minimumScaleFactor
プロパティを適切に設定してください。
とあり、コードでtrueを入れたら、あわせてminimumScaleFactor
も設定しましょう。
minimumScaleFactor
のデフォルト値は0なので、デフォルトだと無限に縮小します。
指定がCGFloatなので、小数点で指定しないといけないのがちょっと直感的じゃないですね。
IBだとフォントサイズで指定できるので、そちらの方が楽そうです。
ドキュメント見ると、
If you specify a value of 0 for this property, the label doesn't scale the text down. The default value of this property is 0.
(抄訳)もしこのプロパティ(minimumScaleFactor
)に0を指定した場合、そのUILabelはテキストを縮小しません。デフォルt値はゼロです。
って書いてあるんで、デフォルト値だと自動縮小効かないって書いてあるように見えるんですが、
手元のシミュレーター(iOS 13.4.1)で試してる限り、無限に縮小する挙動に見えます。
ここはちょっと謎です。
デフォルトの挙動がちょっと怪しいので、最小値を何かしら指定しとくと安心かもです。
注意点2.複数行だと上手く効かないかもしれない
Appleのドキュメントの注意書きで、
This autoshrinking behavior is only intended for use with a single-line label.
(抄訳)この自動縮小機能は一行のラベル向けに使うことのみを想定しています
とあります。
サンプルアプリで
label.numberOfLines = 2
label.text = "Too long string, \nit's very very long string. Extraordinary long string we could not display it"
こんな改行を入れてやってみたんですが、普通にいい感じに縮小されたので、効くときは効くみたいです。