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)
    }
}