SwiftUI TextEditor 禁用编辑但保持可点击
SwiftUI TextEditor disable editing but keep tapable
我有一个 TextEditor,当用户点击它时会调用 actionSheet,并在其中显示操作 sheet 内容。是否可以保持 TextEditor 可交互但不可编辑?我试过 .disabled() - 但在这种情况下,TextEditor 变得无法使用,因此用户无法调用 ActionSheet。我想避免使用 UIViewRepresentable 来解决这个问题。
import SwiftUI
import NavigationStack
struct CompleteSessionView: View {
@StateObject var viewModel = CompleteSessionViewModel()
@EnvironmentObject private var navigationStack: NavigationStack
@Binding var isPresented: Bool
@State var sessionManager: SessionManager
@State var showingSkatingStyleSheet = false
var body: some View {
VStack(alignment: .leading, spacing: 5) {
TextBox(text: $viewModel.style, placeholder: "", multiLine:false)
.onTapGesture {
showingSkatingStyleSheet = true
}
}
.actionSheet(isPresented: $showingSkatingStyleSheet) {
styleActionSheet()
}
.onAppear {
viewModel.style = sessionManager.skatingStyle?.localizedString ?? ""
}
}
func styleActionSheet() -> ActionSheet {
return ActionSheet(title: Text("new_sessions_page_style_action_sheet_title".localized), message: Text("new_sessions_page_style_action_sheet_msg".localized), buttons: [
.default(Text(SkatingStyle.streetSkating.localizedString)) {
sessionManager.skatingStyle = .streetSkating
viewModel.style = SkatingStyle.streetSkating.localizedString
},
.default(Text(SkatingStyle.trailSkating.localizedString)) {
sessionManager.skatingStyle = .trailSkating
viewModel.style = SkatingStyle.trailSkating.localizedString
},
.default(Text(SkatingStyle.rollersDance.localizedString)) {
sessionManager.skatingStyle = .rollersDance
viewModel.style = SkatingStyle.rollersDance.localizedString
},
.default(Text(SkatingStyle.freestyle.localizedString)) {
sessionManager.skatingStyle = .freestyle
viewModel.style = SkatingStyle.freestyle.localizedString
},
.default(Text(SkatingStyle.rollerDerby.localizedString)) {
sessionManager.skatingStyle = .rollerDerby
viewModel.style = SkatingStyle.rollerDerby.localizedString
},
.default(Text(SkatingStyle.aggresive.localizedString)) {
sessionManager.skatingStyle = .aggresive
viewModel.style = SkatingStyle.aggresive.localizedString
},
.default(Text(SkatingStyle.indoorRinks.localizedString)) {
sessionManager.skatingStyle = .indoorRinks
viewModel.style = SkatingStyle.indoorRinks.localizedString
},
.default(Text(SkatingStyle.artistic.localizedString)) {
sessionManager.skatingStyle = .artistic
viewModel.style = SkatingStyle.artistic.localizedString
},
.cancel()
])
}
}
struct TextBox: View {
@Binding var text: String
var placeholder: String
var multiLine: Bool
var body: some View {
ZStack(alignment: .topLeading) {
TextEditor(text: $text)
.introspectTextField { textfield in
textfield.returnKeyType = .next
}
.background(Color.white)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color.black, lineWidth: 1)
)
.padding(.horizontal, 8)
if text.isEmpty {
Text(placeholder)
.foregroundColor(.black.opacity(0.25))
.padding(.top, 8)
.padding(.horizontal, 12)
.allowsHitTesting(false)
}
}
}
}
Is it possible to keep TextEditor interactable but not editable?
是的。您可以给预期参数 text
一个 constant
。您可以以正常方式与其交互,但无法编辑文本。
例如
struct ContentView: View {
@State var text = "Placeholder"
var body: some View {
SecondView(text: self.$text)
}
}
struct SecondView: View {
@Binding var text: String
var body: some View {
TextEditor(text: .constant(self.text))
.padding(50)
}
}
我有一个 TextEditor,当用户点击它时会调用 actionSheet,并在其中显示操作 sheet 内容。是否可以保持 TextEditor 可交互但不可编辑?我试过 .disabled() - 但在这种情况下,TextEditor 变得无法使用,因此用户无法调用 ActionSheet。我想避免使用 UIViewRepresentable 来解决这个问题。
import SwiftUI
import NavigationStack
struct CompleteSessionView: View {
@StateObject var viewModel = CompleteSessionViewModel()
@EnvironmentObject private var navigationStack: NavigationStack
@Binding var isPresented: Bool
@State var sessionManager: SessionManager
@State var showingSkatingStyleSheet = false
var body: some View {
VStack(alignment: .leading, spacing: 5) {
TextBox(text: $viewModel.style, placeholder: "", multiLine:false)
.onTapGesture {
showingSkatingStyleSheet = true
}
}
.actionSheet(isPresented: $showingSkatingStyleSheet) {
styleActionSheet()
}
.onAppear {
viewModel.style = sessionManager.skatingStyle?.localizedString ?? ""
}
}
func styleActionSheet() -> ActionSheet {
return ActionSheet(title: Text("new_sessions_page_style_action_sheet_title".localized), message: Text("new_sessions_page_style_action_sheet_msg".localized), buttons: [
.default(Text(SkatingStyle.streetSkating.localizedString)) {
sessionManager.skatingStyle = .streetSkating
viewModel.style = SkatingStyle.streetSkating.localizedString
},
.default(Text(SkatingStyle.trailSkating.localizedString)) {
sessionManager.skatingStyle = .trailSkating
viewModel.style = SkatingStyle.trailSkating.localizedString
},
.default(Text(SkatingStyle.rollersDance.localizedString)) {
sessionManager.skatingStyle = .rollersDance
viewModel.style = SkatingStyle.rollersDance.localizedString
},
.default(Text(SkatingStyle.freestyle.localizedString)) {
sessionManager.skatingStyle = .freestyle
viewModel.style = SkatingStyle.freestyle.localizedString
},
.default(Text(SkatingStyle.rollerDerby.localizedString)) {
sessionManager.skatingStyle = .rollerDerby
viewModel.style = SkatingStyle.rollerDerby.localizedString
},
.default(Text(SkatingStyle.aggresive.localizedString)) {
sessionManager.skatingStyle = .aggresive
viewModel.style = SkatingStyle.aggresive.localizedString
},
.default(Text(SkatingStyle.indoorRinks.localizedString)) {
sessionManager.skatingStyle = .indoorRinks
viewModel.style = SkatingStyle.indoorRinks.localizedString
},
.default(Text(SkatingStyle.artistic.localizedString)) {
sessionManager.skatingStyle = .artistic
viewModel.style = SkatingStyle.artistic.localizedString
},
.cancel()
])
}
}
struct TextBox: View {
@Binding var text: String
var placeholder: String
var multiLine: Bool
var body: some View {
ZStack(alignment: .topLeading) {
TextEditor(text: $text)
.introspectTextField { textfield in
textfield.returnKeyType = .next
}
.background(Color.white)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color.black, lineWidth: 1)
)
.padding(.horizontal, 8)
if text.isEmpty {
Text(placeholder)
.foregroundColor(.black.opacity(0.25))
.padding(.top, 8)
.padding(.horizontal, 12)
.allowsHitTesting(false)
}
}
}
}
Is it possible to keep TextEditor interactable but not editable?
是的。您可以给预期参数 text
一个 constant
。您可以以正常方式与其交互,但无法编辑文本。
例如
struct ContentView: View {
@State var text = "Placeholder"
var body: some View {
SecondView(text: self.$text)
}
}
struct SecondView: View {
@Binding var text: String
var body: some View {
TextEditor(text: .constant(self.text))
.padding(50)
}
}