Guest User

Untitled

a guest
Nov 7th, 2020
683
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 3.10 KB | None | 0 0
  1. import SwiftUI
  2.  
  3. struct ManagedTextView: UIViewRepresentable {
  4.     typealias UIViewType = UITextView
  5.  
  6.     @Binding var text: String
  7.     let textDidChange: ((UITextView) -> Void)?
  8.    
  9.     init(text: Binding<String>, textDidChange: ((UITextView) -> Void)? = nil) {
  10.         self.textDidChange = textDidChange
  11.         self._text = text
  12.     }
  13.  
  14.     func makeUIView(context: Context) -> UITextView {
  15.         let view = UITextView()
  16.         view.isEditable = true
  17.         view.delegate = context.coordinator
  18.         view.font = UIFont.preferredFont(forTextStyle: .body)
  19.         view.adjustsFontForContentSizeCategory = true
  20.         view.backgroundColor = .clear
  21.         return view
  22.     }
  23.  
  24.     func updateUIView(_ uiView: UITextView, context: Context) {
  25.         uiView.text = self.text
  26.         DispatchQueue.main.async {
  27.             self.textDidChange?(uiView)
  28.         }
  29.     }
  30.  
  31.     func makeCoordinator() -> Coordinator {
  32.         return Coordinator(text: $text, textDidChange: textDidChange)
  33.     }
  34.  
  35.     class Coordinator: NSObject, UITextViewDelegate {
  36.         @Binding var text: String
  37.         let textDidChange: ((UITextView) -> Void)?
  38.  
  39.         init(text: Binding<String>, textDidChange: ((UITextView) -> Void)?) {
  40.             self._text = text
  41.             self.textDidChange = textDidChange
  42.         }
  43.  
  44.         func textViewDidChange(_ textView: UITextView) {
  45.             self.text = textView.text
  46.             self.textDidChange?(textView)
  47.         }
  48.     }
  49. }
  50.  
  51. struct DynamicTextEditor: View {
  52.     @Environment(\.verticalSizeClass) private var verticalSize
  53.     @Binding var text: String
  54.    
  55.     private let minHeight: CGFloat = UIFont.preferredFont(forTextStyle: .body).pointSize
  56.     @State private var currentHeight: CGFloat?
  57.     let maxHeight: CGFloat?
  58.     let maxHeightCompact: CGFloat?
  59.     let placeholder: String?
  60.    
  61.     private let placeholderPadding: CGFloat = 4
  62.    
  63.     init(text: Binding<String>, placeholder: String? = nil, maxHeight: CGFloat? = nil, maxHeightCompact: CGFloat? = nil) {
  64.         self._text = text
  65.         self.maxHeight = maxHeight
  66.         self.maxHeightCompact = maxHeightCompact
  67.         self.placeholder = placeholder
  68.     }
  69.    
  70.     var body: some View {
  71.         ManagedTextView(text: $text, textDidChange: textDidChange(_:))
  72.             .frame(height: frameHeight)
  73.             .background(Text(placeholder ?? "")
  74.                             .foregroundColor(.secondaryLabel)
  75.                             .opacity(text.count == 0 ? 1.0 : 0)
  76.                             .padding(.leading, placeholderPadding),
  77.                         alignment: .leading)
  78.     }
  79.    
  80.     private var frameHeight: CGFloat {
  81.         if verticalSize == .compact, let maxHeightCompact = maxHeightCompact {
  82.             return min(currentHeight ?? minHeight, maxHeightCompact)
  83.         } else if let maxHeight = maxHeight {
  84.             return min(currentHeight ?? minHeight, maxHeight)
  85.         } else {
  86.             return currentHeight ?? minHeight
  87.         }
  88.     }
  89.    
  90.     private func textDidChange(_ textView: UITextView) {
  91.         currentHeight = textView.contentSize.height
  92.     }
  93. }
Advertisement
Add Comment
Please, Sign In to add comment