ここで説明されているように、TextView UIViewRepresentable を使用しています https://www.appcoda.com/swiftui-textview-uiviewrepresentable/。
行間隔に関する1つの問題を除けば、期待どおりに機能しています。SwiftUI の lineSpacing 修飾子は効果がないようです。そのため、UIViewRepresentable に以下を追加して回避しました
func updateUIView(_ uiView: UITextView, context: Context)
。
let style = NSMutableParagraphStyle()
style.lineSpacing = 4
let attributes = [NSAttributedString.Key.paragraphStyle : style]
uiView.attributedText = NSAttributedString(string: self.text, attributes:attributes)
これは、 UITextView の行間を調整することでアドバイスされたとおりです。
したがって、完全な関数は次のようになります。
func updateUIView(_ uiView: UITextView, context: Context) {
uiView.text = text
// line spacing
let style = NSMutableParagraphStyle()
style.lineSpacing = 4
let attributes = [NSAttributedString.Key.paragraphStyle : style]
uiView.attributedText = NSAttributedString(string: self.text, attributes:attributes)
}
これで問題はありませんが、UndoManager がリセットされます。つまり、何らかの変更を加えるとすぐに、UndoManager は元に戻す (またはやり直す) ことができるものがあるとは認識しません。私の検索から、これは attributedText の値を変更することの一般的な副作用のようです。私のアプローチを微調整するか、 UndoManager の状態をリセットせずに lineSpacing を達成するまったく別の方法かどうか、利用可能な回避策があるかどうか疑問に思っています。
UPDATE : Asperi の推奨を試みましたが、結果はさまざまでした。
これは、TextView と対応するコーディネーターの完全なコードです。
import SwiftUI
struct TextView: UIViewRepresentable {
// MARK: Bindings
@Binding var text: String
@Binding var textStyle: UIFont.TextStyle
// MARK: -
// MARK: Functions
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.backgroundColor = UIColor.clear
textView.delegate = context.coordinator
textView.autocapitalizationType = .sentences
textView.isSelectable = true
textView.isUserInteractionEnabled = true
textView.adjustsFontForContentSizeCategory = true
return textView
}
func makeCoordinator() -> Coordinator {
Coordinator($text)
}
func updateUIView(_ uiView: UITextView, context: Context) {
let storage = uiView.textStorage
storage.beginEditing()
// line spacing
let style = NSMutableParagraphStyle()
style.lineSpacing = 4
let attributes = [NSAttributedString.Key.paragraphStyle : style]
storage.replaceCharacters(in: NSRange(location: 0, length: storage.length),
with: NSAttributedString(string: self.text, attributes:attributes))
storage.endEditing()
}
// MARK: -
// MARK: Internal classes
class Coordinator: NSObject, UITextViewDelegate {
// MARK: Local
var text: Binding<String>
// MARK: -
init(_ text: Binding<String>) {
self.text = text
}
// MARK: -
// MARK: Functions
func textViewDidChange(_ textView: UITextView) {
self.text.wrappedValue = textView.text
}
}
}
self.text.wrappedValue = textView.text を textViewDidChange (上部にリンクされている AppCoda チュートリアルから取得したもの) に保持すると、推奨事項は機能しません。ただし、削除すると機能するように見えますが、ビューが更新されるたびに、セッションの開始時にテキストが自動的に元の状態にリセットされるという他の問題があります。たとえば、別のビューに切り替えようとした場合などです。アプリで、そうする前にテキストがリセットされるのを確認できました。または、たとえば、TextView の不透明度を下げる UI を開いたときに確認できました。