【问题标题】:Change background color of TextEditor in SwiftUI在 SwiftUI 中更改 TextEditor 的背景颜色
【发布时间】:2020-11-01 00:30:15
【问题描述】:

TextEditor 似乎有默认的白色背景。所以以下内容不起作用,它显示为white,而不是定义的red

var body: some View {
    TextEditor(text: .constant("Placeholder"))
        .background(Color.red)
}

是否可以将颜色更改为自定义颜色?

【问题讨论】:

  • 在 macOS 上,对我来说,它解决了 this 接受的答案。
  • 在 macOS 上,对我来说,它解决了 this 接受的答案。

标签: swift swiftui


【解决方案1】:
extension View {
/// Layers the given views behind this ``TextEditor``.
    func textEditorBackground<V>(@ViewBuilder _ content: () -> V) -> some View where V : View {
        self
            .onAppear {
                UITextView.appearance().backgroundColor = .clear
            }
            .background(content())
    }
}

【讨论】:

    【解决方案2】:

    您可以使用 .introspectTextView 更改背景颜色。

                 TextEditor(text: .constant("Placeholder"))
                    .cornerRadius(8)
                    .frame(height: 100)
                    .introspectTextView { textView in
                        textView.backgroundColor = UIColor(Color.red)
                    }
    

    Result

    【讨论】:

      【解决方案3】:

      TextEditorUITextView 支持。所以你需要先去掉UITextViewbackgroundColor,然后你可以将任何View设置为background

      struct ContentView: View {
          init() {
              UITextView.appearance().backgroundColor = .clear
          }
      
          var body: some View {
              List {
                  TextEditor(text: .constant("Placeholder"))
                      .background(Color.red)
              }
          }
      }
      

      演示

      你可以找到我的增长TextEditor的简单技巧here in this answer

      【讨论】:

      • 为了扩展这个问题/答案 - 因为 SwiftUI 也支持 macOS 应用程序,你将如何使用基于 NSTextViewTextEditor 做同样的事情?
      • 天才,要是 Apple 的员工能为我们做到这一点就好了!
      • 同意,我希望苹果能尽快解决这个问题,但不会像往常一样向后兼容。所以不幸的是,我们应该坚持一段时间。 @AntonínKarásek。
      • 在 OS X 上用 NSTextVIew 回答,看来你不知道。已经尝试这样做了2天。 Apple 非常棒,设置背景颜色是一项先进技术。
      【解决方案4】:

      iOS 和 macOS 上的纯 SwiftUI 解决方案

      colorMultiply 是你的朋友。

      struct ContentView: View {
          
          @State private var editingText: String = ""
          
          var body: some View {
              
              TextEditor(text: $editingText)
                  .frame(width: 400, height: 100, alignment: .center)
                  .cornerRadius(3.0)
                  .colorMultiply(.gray)
          }
      }
      

      【讨论】:

      • 这将覆盖文本颜色
      【解决方案5】:

      在 macOS 上使用 SwiftUI 自定义背景颜色

      不幸的是,在 macOS 上,您必须回退到 AppKit 并包装 NSTextView。

      你需要声明一个符合NSViewRepresentable的视图

      这应该为您提供与 SwiftUI 的 TextEditor-View 几乎相同的行为,并且由于包装的 NSTextView 不绘制其背景,您可以使用 .background-ViewModifier 更改背景

      struct CustomizableTextEditor: View {
          @Binding var text: String
          
          var body: some View {
              GeometryReader { geometry in
                  NSScrollableTextViewRepresentable(text: $text, size: geometry.size)
              }
          }
          
      }
      
      struct NSScrollableTextViewRepresentable: NSViewRepresentable {
          typealias Representable = Self
          
          // Hook this binding up with the parent View
          @Binding var text: String
          var size: CGSize
          
          // Get the UndoManager
          @Environment(\.undoManager) var undoManger
          
          // create an NSTextView
          func makeNSView(context: Context) -> NSScrollView {
              
              // create NSTextView inside NSScrollView
              let scrollView = NSTextView.scrollableTextView()
              let nsTextView = scrollView.documentView as! NSTextView
              
              // use SwiftUI Coordinator as the delegate
              nsTextView.delegate = context.coordinator
              
              // set drawsBackground to false (=> clear Background)
              // use .background-modifier later with SwiftUI-View
              nsTextView.drawsBackground = false
              
              // allow undo/redo
              nsTextView.allowsUndo = true
              
              return scrollView
          }
          
          func updateNSView(_ scrollView: NSScrollView, context: Context) {
              // get wrapped nsTextView
              guard let nsTextView = scrollView.documentView as? NSTextView else {
                  return
              }
              
              // fill entire given size
              nsTextView.minSize = size
              
              // set NSTextView string from SwiftUI-Binding
              nsTextView.string = text
          }
          
          // Create Coordinator for this View
          func makeCoordinator() -> Coordinator {
              Coordinator(self)
          }
          
          // Declare nested Coordinator class which conforms to NSTextViewDelegate
          class Coordinator: NSObject, NSTextViewDelegate {
              var parent: Representable // store reference to parent
              
              init(_ textEditor: Representable) {
                  self.parent = textEditor
              }
              
              // delegate method to retrieve changed text
              func textDidChange(_ notification: Notification) {
                  // check that Notification.name is of expected notification
                  // cast Notification.object as NSTextView
      
                  guard notification.name == NSText.didChangeNotification,
                      let nsTextView = notification.object as? NSTextView else {
                      return
                  }
                  // set SwiftUI-Binding
                  parent.text = nsTextView.string
              }
              
              // Pass SwiftUI UndoManager to NSTextView
              func undoManager(for view: NSTextView) -> UndoManager? {
                  parent.undoManger
              }
      
              // feel free to implement more delegate methods...
              
          }
          
      }
      

      用法

      ContenView: View {
          @State private var text: String
      
          var body: some View {
              VStack {
                  Text("Enter your text here:")
                  CustomizableTextEditor(text: $text)
                      .background(Color.red)
              }
                  .frame(minWidth: 600, minHeight: 400)
      
          }
      }
      

      编辑:

      • 将引用传递给 SwiftUI UndoManager,以便可以使用默认的撤消/重做操作。
      • 将 NSTextView 包装在 NSScrollView 中,使其可滚动。将 NSTextView 的 minSize 属性设置为封闭 SwiftUIView-Size 以便它填充整个允许的空间。

      警告:只有此自定义 TextEditor 的第一行可单击以启用文本编辑。

      【讨论】:

      • 我投了你一票,因为它也适用于 macOS,但开销太大
      • 是的,它需要很多代码来简单地改变背景颜色,但这是一个有趣的练习。我尝试了您的解决方案,但 .colorMultiply() 实际上将所有颜色混合在一起(例如,如果您乘以 Color.clear,您将看不到任何东西)。或者我可能错过了一些东西,但你提供的代码对我不起作用
      猜你喜欢
      • 2020-11-28
      • 1970-01-01
      • 1970-01-01
      • 2020-10-11
      • 2021-07-25
      • 2020-03-02
      • 2021-02-11
      • 2020-01-01
      相关资源
      最近更新 更多