在 SwiftUI 中更改 TextEditor 的背景颜色

Lor*_*ngo 29 swift swiftui

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

var body: some View {
    TextEditor(text: .constant("Placeholder"))
        .background(Color.red)
}
Run Code Online (Sandbox Code Playgroud)

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

Moj*_*ini 61

TextEditorUITextView. 所以你需要先去掉UITextView'sbackgroundColor然后你可以设置 anyViewbackground.

struct ContentView: View {
    init() {
        UITextView.appearance().backgroundColor = .clear
    }

    var body: some View {
        List {
            TextEditor(text: .constant("Placeholder"))
                .background(Color.red)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

演示

在此处输入图片说明

您可以在此答案中找到我在此处增加 TextEditor 的简单技巧

  • 天才,如果苹果公司的员工能为我们做到这一点就好了! (9认同)
  • 我是唯一一个看到使用“UITextView.appearance()”作为解决方法的危险的人吗?它会更改整个应用程序的“UITextView”的配置? (7认同)
  • 扩展这个问题/答案 - 因为 SwiftUI 也支持 macOS 应用程序,所以你如何使用基于“NSTextView”的“TextEditor”做同样的事情? (4认同)
  • 这在 iOS 16 beta 4 中似乎不起作用。 (2认同)

Mar*_* T. 18

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这将覆盖文本颜色 (17认同)
  • 另外它在黑暗模式下不起作用.. (4认同)
  • 无法在深色模式下工作 (4认同)

Nik*_*las 18

正如许多人所说,对于 iOS 16,您需要使用scrollContentBackground. 我创建了一个扩展方法来处理这两种情况:

struct ContentView: View {
    @State private var editingText: String = ""
    
    var body: some View {
        TextEditor(text: $editingText)
            .transparentScrolling()
            .background(Color.red)
    }
}

public extension View {
    func transparentScrolling() -> some View {
        if #available(iOS 16.0, *) {
            return scrollContentBackground(.hidden)
        } else {
            return onAppear {
                UITextView.appearance().backgroundColor = .clear
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是唯一满足所有要求的解决方案(所有 iOS,所有模式) (2认同)

Stu*_* mc 10

更新 iOS 16 / SwiftUI 4.0

你需要使用.scrollContentBackground(.hidden)而不是UITextView.appearance().backgroundColor = .clear

https://twitter.com/StuFFmc/status/1556561422431174656

警告:这仅适用于 iOS 16,因此您可能需要一些if #available (甚至可能是两个)不同的TextEditor组件。


小智 8

这对我在 macOS 上有效

extension NSTextView {
  open override var frame: CGRect {
    didSet {
      backgroundColor = .clear
      drawsBackground = true
    }
  }
}
struct ContentView: View {
    @State var text = ""
    var body: some View {        
        TextEditor(text: $text)           
            .background(Color.red)    
    }
Run Code Online (Sandbox Code Playgroud)

参考这个答案


小智 8

Ios 16
确保添加 .scrollContentBackground(.hidden) 这行然后背景将应用

TextEditor(text:.constant(hint))
.scrollContentBackground(.hidden)
.background(.red) // To see this
Run Code Online (Sandbox Code Playgroud)

这对我来说工作


Reb*_*per 6

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())
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

为了实现这种视觉设计,我使用了代码。

在此输入图像描述

iOS 16

TextField(
    "free_form",
    text: $comment,
    prompt: Text("Type your feedback..."),
    axis: .vertical
)
.lineSpacing(10.0)
.lineLimit(10...)
.padding(16)
.background(Color.themeSeashell)
.cornerRadius(16)
Run Code Online (Sandbox Code Playgroud)

iOS 15

ZStack(alignment: .topLeading) {
    RoundedRectangle(cornerRadius: 16)
        .foregroundColor(.gray)
    
    TextEditor(text: $comment)
        .padding()
        .focused($isFocused)
    
    if !isFocused {
        Text("Type your feedback...")
            .padding()
    }
}
.frame(height: 132)
.onAppear() {
    UITextView.appearance().backgroundColor = .clear
}
Run Code Online (Sandbox Code Playgroud)


til*_*ain 5

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

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

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

这应该为您提供与 SwiftUI 的 -View 几乎相同的行为TextEditor,并且由于包装的 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...
        
    }
    
}
Run Code Online (Sandbox Code Playgroud)

用法

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)

    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

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

注意:只能单击此自定义文本编辑器的第一行来启用文本编辑。