Created
June 13, 2023 20:42
-
-
Save jamesporter/6d9b51afcd24058e3a2bff210a581771 to your computer and use it in GitHub Desktop.
Equation Editing in SwiftUI with Swift Math
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import SwiftMath | |
enum ContentItem: Identifiable { | |
case text(_ text: String, id: Int) | |
case equation(_ equation: String, id: Int) | |
// this is obviously very simplistic/needs improvement if to be used for reals | |
static func parse(input: String) -> [ContentItem] { | |
let items = input.split(separator: "$$\n") | |
if items.count == 1 { | |
return [.text(input, id: 0)] | |
} else { | |
var result: [ContentItem] = [] | |
var i = 0 | |
items.forEach { part in | |
let s = String(part).trimmingCharacters(in: .whitespacesAndNewlines) | |
if i % 2 == 0 { | |
result.append(.text(s, id: i)) | |
} else { | |
result.append(.equation(s, id: i)) | |
} | |
i += 1 | |
} | |
return result | |
} | |
} | |
var id: Int { | |
switch self { | |
case .equation(_, let id): | |
return id | |
case .text(_, let id): | |
return id | |
} | |
} | |
} | |
struct ContentView: View { | |
@State private var text: String = "" | |
var content: [ContentItem] { | |
ContentItem.parse(input: text) | |
} | |
var body: some View { | |
VStack { | |
TextEditor(text: $text) | |
.padding() | |
.frame(maxHeight: .infinity) | |
.border(.red) | |
ScrollView { | |
LazyVStack { | |
ForEach(content) { item in | |
switch item { | |
case let .equation(eq,_): | |
MathView(equation: eq, fontSize: 16).fixedSize(horizontal: false, vertical: true).tag(item.id) | |
case let .text(text,_): | |
Text(text).tag(item.id) | |
} | |
} | |
}.padding() | |
} | |
.frame(maxHeight: .infinity) | |
.border(.yellow) | |
} | |
.padding() | |
} | |
} | |
struct ContentView_Previews: PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} | |
struct MathView: UIViewRepresentable { | |
var equation: String | |
var fontSize: CGFloat | |
func makeUIView(context: Context) -> MTMathUILabel { | |
let view = MTMathUILabel() | |
return view | |
} | |
func updateUIView(_ uiView: MTMathUILabel, context: Context) { | |
uiView.latex = equation | |
uiView.fontSize = fontSize | |
uiView.font = MTFontManager().termesFont(withSize: fontSize) | |
uiView.textAlignment = .center | |
uiView.labelMode = .display | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment