sal*_*000 7 uiscrollview uitextview ios swift swiftui
我正在构建一个 SwiftUI 应用程序,我想将一个可编辑的 UITextView (包装在 UIViewRepresentable 中)放入 SwiftUI ScrollView 中。原因是我有其他 SwiftUI 内容想要放在文本上方,并且我希望它与文本一起滚动。我需要一个 TextView,因为我想要富文本和工具栏。
我想我可以禁用 UITextView 上的滚动并赋予它无限的高度,但这也赋予它无限的宽度,因此文本会水平滚动屏幕边缘,直到添加换行符。我尝试将文本视图的内容大小和框架大小设置为屏幕宽度,如如何在 UITextView 中禁用垂直滚动?但我无法让它发挥作用。我可以成功更新 textview 内容大小,但更改似乎稍后会被覆盖(请参阅 textViewDidChange 中的打印语句)。
有什么方法可以实现这一点吗?即 SwiftUI ScrollView 内的可编辑 UITextView。提前致谢!
import SwiftUI
struct TextView: UIViewRepresentable {
var attributedString: NSAttributedString
var fixedWidth: CGFloat
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, UITextViewDelegate {
var parent: TextView
init(_ parent: TextView) {
self.parent = parent
}
func textViewDidChange(_ textView: UITextView) {
print("pre content size update: \(textView.contentSize)") // width is over limit
let newSize = textView.sizeThatFits(CGSize(width: parent.fixedWidth, height: CGFloat.greatestFiniteMagnitude))
textView.contentSize = CGSize(width: max(newSize.width, parent.fixedWidth), height: newSize.height)
print("post content size update: \(textView.contentSize)") // width is updated
}
}
func makeUIView(context: Context) -> UITextView {
let textView = UITextView(frame: .zero)
textView.isEditable = true
textView.isScrollEnabled = false
textView.backgroundColor = .cyan // just to make it easier to see
textView.delegate = context.coordinator
return textView
}
func updateUIView(_ textView: UITextView, context: Context) {
textView.attributedText = self.attributedString
}
}
struct ContentView: View {
var body: some View {
GeometryReader { geo in
ScrollView(.vertical) {
VStack(alignment: .leading, spacing: /*@START_MENU_TOKEN@*/nil/*@END_MENU_TOKEN@*/){
//Other content
Image(systemName: "photo")
.font(.largeTitle)
Button("A button"){
print("i'm a button")
}
//Editable textview
TextView(attributedString: NSAttributedString(string: "Here is a long string as you can see it is not wrapping but instead scrolling off the edge of the screen"), fixedWidth: geo.size.width)
.frame(width: geo.size.width)
.frame(maxHeight: .infinity)
}
.padding(.horizontal)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的其他一些事情:
将宽度约束设置为文本视图并设置GeometryReader
在视图的顶部。
之所以设置GeometryReader
在顶部,是因为在滚动视图内部它不允许完全滚动。
UIViewRepresentable Text View
struct TextView: UIViewRepresentable {
var attributedString: NSAttributedString
var fixedWidth: CGFloat
let textView = UITextView(frame: .zero)
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, UITextViewDelegate {
var parent: TextView
init(_ parent: TextView) {
self.parent = parent
}
}
func makeUIView(context: Context) -> UITextView {
textView.isEditable = true
textView.isScrollEnabled = false
textView.backgroundColor = .cyan // just to make it easier to see
textView.delegate = context.coordinator
textView.translatesAutoresizingMaskIntoConstraints = false
textView.widthAnchor.constraint(equalToConstant: fixedWidth).isActive = true //<--- Here
return textView
}
func updateUIView(_ textView: UITextView, context: Context) {
DispatchQueue.main.async { //<--- Here
textView.attributedText = self.attributedString
}
}
}
Run Code Online (Sandbox Code Playgroud)
ContentView
struct ContentView: View {
@State private var textViewSize: CGSize = CGSize()
var body: some View {
GeometryReader { geo in //<--- Here
ScrollView(.vertical) {
VStack(alignment: .leading, spacing: 0){
//Other content
Image(systemName: "photo")
.font(.largeTitle)
Button("A button"){
print("i'm a button")
}
TextView(attributedString: NSAttributedString(string: "Here is a long string as you can see it is not wrapping but instead scrolling off the edge of the screenHere is a long string as you can see it is not wrapping but instead scrolling off the edge of the screenHere is a long string as you can see it is not wrapping but instead scrolling off the edge of the screenHere is a long string as you can see it is not wrapping but instead scrolling off the edge of the screenHere is a long string as you can see it is \n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new line\n1new lineinstead scrolling off the edge of the screenHere is a long string as you can see it is not wrapping but instead scrolling off the edge of the screenHere is a long string as you can see it is not wrapping but instead scrolling off the edge of the screen ------end"), fixedWidth: geo.size.width - 15 * 2) //<--- Here minus the padding for both size
}.padding(.horizontal, 15)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1649 次 |
最近记录: |