0

ここで説明されているように、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 を開いたときに確認できました。

4

1 に答える 1

0

https://stackoverflow.com/a/44414510/698971の Ivan の回答のおかげで、正しいアプローチに出くわした可能性があります。

func makeUIView(context: Context) -> UITextViewTextView UIViewRepresentable の内部で、次を追加する必要がありました。

    let spacing = NSMutableParagraphStyle()
    spacing.lineSpacing = 4
    let attr = [NSAttributedString.Key.paragraphStyle : spacing]
    textView.typingAttributes = attr
于 2020-12-09T16:34:05.227 に答える