106 lines
3.0 KiB
Swift
106 lines
3.0 KiB
Swift
//
|
|
// StatusEditorView.swift
|
|
//
|
|
//
|
|
// Created by MainasuK Cirno on 2021-7-16.
|
|
//
|
|
|
|
import UIKit
|
|
import SwiftUI
|
|
import UITextView_Placeholder
|
|
|
|
public struct StatusEditorView: UIViewRepresentable {
|
|
|
|
@Binding var string: String
|
|
let placeholder: String
|
|
let width: CGFloat
|
|
let attributedString: NSAttributedString
|
|
let keyboardType: UIKeyboardType
|
|
@Binding var viewDidAppear: Bool
|
|
|
|
public init(
|
|
string: Binding<String>,
|
|
placeholder: String,
|
|
width: CGFloat,
|
|
attributedString: NSAttributedString,
|
|
keyboardType: UIKeyboardType,
|
|
viewDidAppear: Binding<Bool>
|
|
) {
|
|
self._string = string
|
|
self.placeholder = placeholder
|
|
self.width = width
|
|
self.attributedString = attributedString
|
|
self.keyboardType = keyboardType
|
|
self._viewDidAppear = viewDidAppear
|
|
}
|
|
|
|
public func makeUIView(context: Context) -> UITextView {
|
|
let textView = UITextView(frame: .zero)
|
|
textView.placeholder = placeholder
|
|
|
|
textView.isScrollEnabled = false
|
|
textView.font = .preferredFont(forTextStyle: .body)
|
|
textView.textColor = .label
|
|
textView.keyboardType = keyboardType
|
|
textView.delegate = context.coordinator
|
|
textView.backgroundColor = .clear
|
|
|
|
textView.translatesAutoresizingMaskIntoConstraints = false
|
|
let widthLayoutConstraint = textView.widthAnchor.constraint(equalToConstant: 100)
|
|
widthLayoutConstraint.priority = .required - 1
|
|
context.coordinator.widthLayoutConstraint = widthLayoutConstraint
|
|
|
|
return textView
|
|
}
|
|
|
|
public func updateUIView(_ textView: UITextView, context: Context) {
|
|
// preserve currently selected text range to prevent cursor jump
|
|
let currentlySelectedRange = textView.selectedRange
|
|
|
|
// update content
|
|
// textView.attributedText = attributedString
|
|
textView.text = string
|
|
|
|
// update layout
|
|
context.coordinator.updateLayout(width: width)
|
|
|
|
// set becomeFirstResponder
|
|
if viewDidAppear {
|
|
viewDidAppear = false
|
|
textView.becomeFirstResponder()
|
|
}
|
|
|
|
// restore selected text range
|
|
textView.selectedRange = currentlySelectedRange
|
|
}
|
|
|
|
public func makeCoordinator() -> Coordinator {
|
|
Coordinator(self)
|
|
}
|
|
|
|
public class Coordinator: NSObject, UITextViewDelegate {
|
|
var parent: StatusEditorView
|
|
var widthLayoutConstraint: NSLayoutConstraint?
|
|
|
|
init(_ parent: StatusEditorView) {
|
|
self.parent = parent
|
|
}
|
|
|
|
public func textViewDidChange(_ textView: UITextView) {
|
|
// prevent break IME input
|
|
if textView.markedTextRange == nil {
|
|
parent.string = textView.text
|
|
}
|
|
}
|
|
|
|
func updateLayout(width: CGFloat) {
|
|
guard let widthLayoutConstraint = widthLayoutConstraint else { return }
|
|
widthLayoutConstraint.constant = width
|
|
widthLayoutConstraint.isActive = true
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|