Page Menu
Home
Musing Studio
Search
Configure Global Search
Log In
Files
F10882869
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Subscribers
None
View Options
diff --git a/iOS/PostEditor/PostTitleTextView.swift b/iOS/PostEditor/PostTitleTextView.swift
index f36a2bb..c29f843 100644
--- a/iOS/PostEditor/PostTitleTextView.swift
+++ b/iOS/PostEditor/PostTitleTextView.swift
@@ -1,20 +1,95 @@
-//
-// PostTitleTextView.swift
-// WriteFreely-MultiPlatform (iOS)
-//
-// Created by Angelo Stavrow on 2020-10-27.
-//
+// Based on https://lostmoa.com/blog/DynamicHeightForTextFieldInSwiftUI/
+// and https://stackoverflow.com/a/56508132/1234545
import SwiftUI
-struct PostTitleTextView: View {
- var body: some View {
- Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
+class Coordinator: NSObject, UITextViewDelegate, NSLayoutManagerDelegate {
+ @Binding var text: String
+ @Binding var isFirstResponder: Bool
+ var didBecomeFirstResponder: Bool = false
+ var postTitleTextView: PostTitleTextView
+
+ weak var textView: UITextView?
+
+ init(_ textView: PostTitleTextView, text: Binding<String>, isFirstResponder: Binding<Bool>) {
+ self.postTitleTextView = textView
+ _text = text
+ _isFirstResponder = isFirstResponder
+ }
+
+ func textViewDidChangeSelection(_ textView: UITextView) {
+ DispatchQueue.main.async {
+ self.postTitleTextView.text = textView.text ?? ""
+ }
+ }
+
+ func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
+ if (text == "\n") {
+ self.isFirstResponder.toggle()
+ return false
+ }
+ return true
+ }
+
+ func layoutManager(
+ _ layoutManager: NSLayoutManager,
+ didCompleteLayoutFor textContainer: NSTextContainer?,
+ atEnd layoutFinishedFlag: Bool
+ ) {
+ DispatchQueue.main.async {
+ guard let view = self.textView else {
+ return
+ }
+ let size = view.sizeThatFits(view.bounds.size)
+ if self.postTitleTextView.height != size.height {
+ self.postTitleTextView.height = size.height
+ }
+ }
}
}
-struct PostTitleTextView_Previews: PreviewProvider {
- static var previews: some View {
- PostTitleTextView()
+struct PostTitleTextView: UIViewRepresentable {
+ @Binding var text: String
+ @Binding var textStyle: UIFont
+ @Binding var height: CGFloat
+ @Binding var isFirstResponder: Bool
+
+ func makeUIView(context: UIViewRepresentableContext<PostTitleTextView>) -> UITextView {
+ let textView = UITextView()
+
+ textView.isEditable = true
+ textView.isUserInteractionEnabled = true
+ textView.isScrollEnabled = true
+ textView.alwaysBounceVertical = false
+
+ context.coordinator.textView = textView
+ textView.delegate = context.coordinator
+ textView.layoutManager.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() -> Coordinator {
+ return Coordinator(self, text: $text, isFirstResponder: $isFirstResponder)
+ }
+
+ func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<PostTitleTextView>) {
+ 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
+ }
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Jul 17, 9:29 PM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3324415
Attached To
rWFSUI WriteFreely SwiftUI
Event Timeline
Log In to Comment