'How to zoom in into a SwiftUI Text Editor
I am building a SwiftUI text editor in which I need the user to be able to zoom in. However, I don't know how to zoom in to the SwiftUI text editor naturally -- I want to make the zooming function of the text editor smooth. In the code below, what I've tried is changing the font size. I've also tried the "scaleEffect" method, but it pixelates the text editor text
Here is a gif of what I essentially want to achieve:

Here is the gif of my current text editor:

Here is my current code:
ScrollView {
VStack {
ForEach(0 ..< wordPad.pages.count) { page in
TextEditor(text: $wordPad.pages[page])
.frame(width: 800 * scale, height: 800 * scale * sqrt(2))
.font(Font.custom(fontName, size: fontSize * scale))
.lineSpacing(10 * scale)
.clipShape(RoundedRectangle(cornerRadius: 5))
.padding(40 * scale)
.foregroundColor(.primary)
.multilineTextAlignment(.leading)
}
}
.frame(maxWidth: .infinity, alignment: .center)
}
.gesture(MagnificationGesture()
.onChanged { scale = $0 }
)
Solution 1:[1]
Changing the type size always leads to different line breaks, because Apple is changing the character spacing based on the display size.
The only workaround I found is to still use .scaleEffect but start with an "enlarged" version of all values (x4) and an initial scale of 0.25 – so it mainly scales down and doesn't pixelate as quickly:
struct ContentView: View {
@State private var wordPad = ""
@State private var scaleGesture: CGFloat = 1
@State private var scale: CGFloat = 0.25
var body: some View {
VStack {
VStack {
TextEditor(text: $wordPad)
.frame(width:1200, height: 1200)
.font(.system(size: 48))
.lineSpacing(40)
.clipShape(RoundedRectangle(cornerRadius: 20))
.multilineTextAlignment(.leading)
.allowsTightening(false)
}
.scaleEffect(scaleGesture * scale)
.gesture(
MagnificationGesture()
.onChanged {
scaleGesture = $0
print($0)
}
.onEnded { value in
print ( scale, value)
scale = scale * scaleGesture
scaleGesture = 1
}
)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.gray)
.ignoresSafeArea()
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
