Textビューをスクロールさせる

はじめに

SwiftUIでTextビューを作りましたが、いざ長文を流し込んでみるとスクロールされないんですね。UIKitのTextViewの感覚でスクロールできると思ったんですが。

というわけで、スクロールさせてみましょう。ただし、UIKitのTextViewをラップしない方法で!

ScrollViewビューにTextビューを乗っけるだけ

GeometryReader { geometry in
    ScrollView(.vertical, showsIndicators: true) {
        Text("a----a----a----a---(略)-a----a----a----a----")
            .multilineTextAlignment(.leading)
            .frame(width: geometry.size.width)
    }
    .frame(maxWidth: .infinity, maxHeight: 360.0)
    .background(Color.white)
}

結果、こうなります。

スクロールバーがちゃんと出ています!

判りにくいですが、右側にスクロールバーが出ています。

ゲシュタルト崩壊的なa----にはあえて突っ込まないでください。
Ipsumにしておけばよかった。

ここでのミソ

なんと言っても、GeometryReaderでしょう。
これがあることにより、Textビューの横幅がScrollViewビューの横幅に一致させることができます。

ここまで言っといてなんですが……

実はGeometryReaderが無くてもTextビューのスクロールを実現できます。

ScrollView(.vertical, showsIndicators: true) {
  Text("a----a----a----a---(略)-a----a----a----a----")
        .multilineTextAlignment(.leading)
        .frame(maxWidth: .infinity)
}
.frame(maxWidth: .infinity, maxHeight: 360.0)
.background(Color.white)
}

なぜあえてGeometryReaderか?
それは親ビューの中での子ビューの位置を知ることができるから。

ここでご紹介したのはTextビューですがImageビューでも応用できるわけです。そしてスクロール方向も縦方向だけでなく横方向もあります。
実験していないですが、ScrollViewビューで表示している領域がスクロール対象の画像のどの領域かを知ることができそうですよね。ということは拡大縮小した画像の一部を切り取る、なんてことができそうですね。

多分何番煎じになるかわからないようなネタですが、これはなかなか夢が広がりますね!

補足

細かいところですが、.multilineTextAlignment(.leading)はテキストが複数行になったとき左寄せにしてくれます。