在SwiftUI中更改文本编辑器的背景颜色

vcirk6k6  于 2022-11-21  发布在  Swift
关注(0)|答案(9)|浏览(271)

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

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

可以把颜色改成自定义的吗?

au9on6nz

au9on6nz1#

为了实现这个可视化设计,我使用了以下代码。

第16版iOS操作系统

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

第15版iOS操作系统

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

pbossiut2#

Using the Introspect library,您可以使用.introspectTextView来变更背景色彩。

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

Result

6vl6ewon

6vl6ewon3#

第16版iOS操作系统
您应该隐藏默认背景以查看所需背景:

TextEditor(text: .constant("Placeholder"))
    .scrollContentBackground(.hidden) // <- Hide it
    .background(.red) // To see this

iOS 15及更低版本

TextEditor是由UITextView支持的。所以你需要先去掉UITextViewbackgroundColor,然后你可以把任何View设置为background

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

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

演示

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

yuvru6vn

yuvru6vn4#

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

vzgqcmou5#

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

pxyaymoc6#

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

不幸的是,在macOS上,您必须回退到AppKit并 Package NSTextView。
您需要声明一个符合NSViewRepresentable的视图
这应该会给予与SwiftUI的TextEditor-View几乎相同的行为,并且由于 Package 的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,以便默认撤消/恢复操作可用
  • 在NSScrollView中 Package NSTextView,使其可滚动。将NSTextView的minSize属性设置为封闭SwiftUIView-Size,使其填充整个允许的空间。

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

f87krz0w

f87krz0w7#

这对我在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)    
    }

Reference this answer

kx1ctssn

kx1ctssn8#

更新iOS 16 /快速用户界面4.0

您需要使用.scrollContentBackground(.hidden)而不是UITextView.appearance().backgroundColor = .clear
https://twitter.com/StuFFmc/status/1556561422431174656
警告:这是一个iOS 16,所以你可能需要一些if #available和潜在的两个不同的TextEditor组件。

snz8szmq

snz8szmq9#

您可以使用Mojtaba的答案(认可的答案)。它在大多数情况下都有效。但是,如果您遇到以下错误:
“从初始设定式传回,但不初始化所有储存的属性”
当尝试使用init{ ... }方法时,请尝试将UITextView.appearance().backgroundColor = .clear添加到.onAppear{ ... }
示例:

var body: some View {
    VStack(alignment: .leading) {

        ...

    }
    .onAppear {
        UITextView.appearance().backgroundColor = .clear
    }
}

相关问题