Skip to content

Instantly share code, notes, and snippets.

@AdamWhitcroft
Created April 5, 2024 19:48
Show Gist options
  • Save AdamWhitcroft/c6ffc0323b9ce227588df7145685ae26 to your computer and use it in GitHub Desktop.
Save AdamWhitcroft/c6ffc0323b9ce227588df7145685ae26 to your computer and use it in GitHub Desktop.
import SwiftUI
import UIKit
struct EditorView<AccessoryShelf: View>: UIViewRepresentable {
// MARK: - Properties
var placeholderText: String
// MARK: - Binding
@Binding var text: String
@Binding var isFirstResponder: Bool
// MARK: - Properties
let accessoryShelf: AccessoryShelf
let padding: CGFloat = 16
/// Creates the `UITextView` instance.
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.delegate = context.coordinator
textView.text = text
textView.font = .rounded(ofSize: 19, weight: .regular)
textView.showsVerticalScrollIndicator = false
textView.textContainer.lineFragmentPadding = 0
textView.textContainerInset = UIEdgeInsets(top: padding, left: padding, bottom: padding, right: padding)
/// Create our placeholder string
/// This is using a private API, so might get rejected for this...
/// https://twitter.com/SebJVidal/status/1749162638573961383
let placeholderAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.rounded(ofSize: 19, weight: .regular),
.foregroundColor: UIColor.placeholderText
]
let attributedPlaceholderString = NSAttributedString(string: Strings.EmptyTextFieldPrompt, attributes: placeholderAttributes)
textView.perform(NSSelectorFromString("setAttributedPlaceholder:"), with: attributedPlaceholderString)
return textView
}
/// Updates the `UITextView` instance.
func updateUIView(_ uiView: UITextView, context: Context) {
uiView.text = text
/// Handles if our `TextView` should enter
/// focused or not.
if isFirstResponder && !uiView.isFirstResponder {
uiView.becomeFirstResponder()
} else if !isFirstResponder && uiView.isFirstResponder {
uiView.resignFirstResponder()
}
}
/// Makes the coordinator to handle text changes.
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextViewDelegate {
var parent: EditorView
init(_ parent: EditorView) {
self.parent = parent
}
func textViewDidChange(_ textView: UITextView) {
DispatchQueue.main.async {
self.parent.text = textView.text
}
}
}
}
private extension UIFont {
class func rounded(ofSize size: CGFloat, weight: UIFont.Weight) -> UIFont {
let systemFont = UIFont.systemFont(ofSize: size, weight: weight)
let font: UIFont
if let descriptor = systemFont.fontDescriptor.withDesign(.rounded) {
font = UIFont(descriptor: descriptor, size: size)
} else {
font = systemFont
}
return font
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment