From aa519354825c9f069eaa4ec2498aa0d674101a5f Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Tue, 27 Oct 2020 14:37:35 -0400 Subject: [PATCH] Create UIViewRepresentable / UITextView for iOS post body editor --- iOS/PostEditor/PostBodyTextView.swift | 62 +++++++++++++++++++++------ 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/iOS/PostEditor/PostBodyTextView.swift b/iOS/PostEditor/PostBodyTextView.swift index 0ca4964..ba7713c 100644 --- a/iOS/PostEditor/PostBodyTextView.swift +++ b/iOS/PostEditor/PostBodyTextView.swift @@ -1,20 +1,54 @@ -// -// PostBodyTextView.swift -// WriteFreely-MultiPlatform (iOS) -// -// Created by Angelo Stavrow on 2020-10-27. -// +// Based on https://stackoverflow.com/a/56508132/1234545 import SwiftUI -struct PostBodyTextView: View { - var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) - } -} +struct PostBodyTextView: UIViewRepresentable { -struct PostBodyTextView_Previews: PreviewProvider { - static var previews: some View { - PostBodyTextView() + class Coordinator: NSObject, UITextViewDelegate { + @Binding var text: String + @Binding var isFirstResponder: Bool + var didBecomeFirstResponder: Bool = false + + init(text: Binding, isFirstResponder: Binding) { + _text = text + _isFirstResponder = isFirstResponder + } + + func textViewDidChangeSelection(_ textView: UITextView) { + DispatchQueue.main.async { + self.text = textView.text ?? "" + } + } + } + + @Binding var text: String + @Binding var textStyle: UIFont + @Binding var isFirstResponder: Bool + + func makeUIView(context: UIViewRepresentableContext) -> UITextView { + let textView = UITextView(frame: .zero) + textView.delegate = context.coordinator + let font = textStyle + let fontMetrics = UIFontMetrics(forTextStyle: .largeTitle) + textView.font = fontMetrics.scaledFont(for: font) + textView.backgroundColor = UIColor.clear + return textView + } + + func makeCoordinator() -> PostBodyTextView.Coordinator { + return Coordinator(text: $text, isFirstResponder: $isFirstResponder) + } + + func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext) { + uiView.text = text + let font = textStyle + let fontMetrics = UIFontMetrics(forTextStyle: .largeTitle) + uiView.font = fontMetrics.scaledFont(for: font) + + // We don't want the text field to become first responder every time SwiftUI refreshes the view. + if isFirstResponder && !context.coordinator.didBecomeFirstResponder { + uiView.becomeFirstResponder() + context.coordinator.didBecomeFirstResponder = true + } } }