У меня есть простое NSViewRepresentable
, которое оборачивает NSTextView
.
struct TextView: NSViewRepresentable {
typealias NSViewType = NSTextView
var text: NSAttributedString
func makeNSView(context: Context) -> NSTextView {
let view = NSTextView()
// set background color to show view bounds
view.backgroundColor = NSColor.systemBlue
view.drawsBackground = true
view.isEditable = false
view.isSelectable = false
return view
}
func updateNSView(_ nsView: NSTextView, context: Context) {
nsView.textStorage?.setAttributedString(text)
}
}
Я хочу центрировать его по вертикали, поэтому я использую VStack
с Spacers
выше и ниже. Я хочу оставить левые и правые поля вокруг него пропорциональными размеру окна, поэтому я обернул их в GeometryReader
и frame()
.
struct ContentView: View {
func textView() -> some View {
let text = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod \
tempor incididunt ut labore et dolore magna aliqua.
"""
// Note: real application has more complex text than this, *not* using
// NSAttributedString isn't really an option, at least till SwiftUI has
// proper rich text support.
let size: CGFloat = 18
let font = NSFont(name: "LeagueSpartan-Bold", size: size)
let attrString = NSAttributedString(
string: text,
attributes: [ .foregroundColor: NSColor.systemYellow,
.font: font ?? NSFont.systemFont(ofSize: size) ])
return TextView(text: attrString)
}
var body: some View {
let textView: some View = self.textView()
return ZStack {
// use ZStack to provide window background color
Color(NSColor.systemTeal)
VStack {
Spacer()
GeometryReader { m2 in
textView.frame(width: m2.size.width / 1.618)
}
Spacer()
}
}
}
}
Горизонтальная рамка работает нормально, но вертикальная интервал вообще не работает:
(начальное состояние)
И изменение размера окна приводит к появлению махинаций:
(изменить размер снизу)
(изменить размер снизу вверх, затем снова вниз)
О, и предварительный просмотр полностью бананов:
Если я заменю свой пользовательский TextView
на SwiftUI
native Text
, макет работает нормально, что говорит о том, что проблема в TextView
. (Обратите также внимание, что размер окна по умолчанию меньше.)
Вероятно, размер NSTextView
установлен неправильно , Если я добавлю nsView.sizeToFit()
к updateNSView()
:
func updateNSView(_ nsView: NSTextView, context: Context) {
nsView.textStorage?.setAttributedString(text)
nsView.sizeToFit()
}
, это уменьшит размер окна по умолчанию и предотвратит отскок текста от нижней части окна при изменении размера вверх и вниз, но текст по-прежнему закреплен в верхней части окна, предварительный просмотр все еще не работает, а при изменении размера снизу все равно NSTextView
временно заполняет большую часть высоты окна.
Другие вещи, которые я пробовал возиться с: isVerticallyResizable
, setContentCompressionResistancePriority
, autoresizingMask
и translatesAutoresizingMaskIntoConstraints
, invalidateIntrinsicContentSize
. Кажется, что ничего из этого не имеет никакого очевидного значения.
Кажется, что я хочу обновить размер NSTextView
, когда изменяются размеры представлений SwiftUI, но, кажется, нет никакого очевидного способа сделать это. это, и я все равно могу ошибаться.