I have a TextEditor that calls actionSheet when user tap on it, and displays action sheet content inside. Is it possible to keep TextEditor interactable but not editable ? I've tried .disabled() - but in this case, TextEditor becomes untapable, so user can't call ActionSheet. I would like to avoid using UIViewRepresentable to solving this.
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?
Yes. You can give a constant
to the expected parameter text
. You can interact with it the normal way but there is no way to edit the text.
E.g.
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)
}
}