You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
4.0 KiB

import SwiftUI
// MARK: -
struct TextInputView: View {
@Binding var content: String
@FocusState var isContentFieldFocused: Bool
let placeholder: String
let maxCharacters: Int
var body: some View {
VStack(spacing: 8) {
ZStack {
//
TextEditor(text: $content)
.frame(minHeight: 120)
.padding(8)
.background(Color(.systemBackground))
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(isContentFieldFocused ? Color.blue : Color(.systemGray4), lineWidth: 1)
)
.focused($isContentFieldFocused)
.onChange(of: content) { newValue in
//
if newValue.count > maxCharacters {
content = String(newValue.prefix(maxCharacters))
}
}
.toolbar {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("完成") {
isContentFieldFocused = false
}
.foregroundColor(.blue)
.font(.system(size: 16, weight: .medium))
}
}
// -
if content.isEmpty && !isContentFieldFocused {
VStack {
HStack {
Text(placeholder)
.foregroundColor(.secondary)
.font(.body)
Spacer()
}
Spacer()
}
.padding(16)
.allowsHitTesting(false)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
}
// -
HStack {
Spacer() // Pushes content to the right
VStack(alignment: .trailing, spacing: 4) {
//
if content.count >= maxCharacters {
HStack(spacing: 4) {
Image(systemName: "exclamationmark.triangle")
.font(.caption)
.foregroundColor(.orange)
Text("已达到最大字符数")
.font(.caption)
.foregroundColor(.orange)
}
} else if content.count >= Int(Double(maxCharacters) * 0.93) {
HStack(spacing: 4) {
Image(systemName: "info.circle")
.font(.caption)
.foregroundColor(.blue)
Text("接近字符限制")
.font(.caption)
.foregroundColor(.blue)
}
}
//
Text("\(content.count)/\(maxCharacters)")
.font(.caption)
.foregroundColor(getCharacterCountColor())
}
}
}
}
private func getCharacterCountColor() -> Color {
if content.count >= maxCharacters {
return .orange
} else if content.count >= Int(Double(maxCharacters) * 0.93) {
return .blue
} else {
return .secondary
}
}
}
#Preview {
TextInputView(
content: .constant(""),
placeholder: "输入任意文本内容...",
maxCharacters: 150
)
}