Add an iPhone client sharing the macOS app's SwiftUI code

This commit is contained in:
Ian Gulliver
2026-10-21 22:00:54 -07:00
parent 57d660c57f
commit 9e81e9107d
46 changed files with 1625 additions and 287 deletions
+63 -4
View File
@@ -1,4 +1,3 @@
import AppKit
import CoreText
import SwiftUI
@@ -280,17 +279,17 @@ private let margin: CGFloat = 20
@MainActor
private var titleFont: CTFont {
Fonts.ns(13, weight: 600) as CTFont
Fonts.native(13, weight: 600) as CTFont
}
@MainActor
private var detailFont: CTFont {
Fonts.ns(12) as CTFont
Fonts.native(12) as CTFont
}
@MainActor
private var edgeLabelFont: CTFont {
Fonts.ns(11) as CTFont
Fonts.native(11) as CTFont
}
@MainActor
@@ -953,6 +952,7 @@ private struct TappableCanvas: View {
}
}
#if os(macOS)
private final class CenteringClipView: NSClipView {
override func constrainBoundsRect(_ proposedBounds: NSRect) -> NSRect {
var r = super.constrainBoundsRect(proposedBounds)
@@ -1007,3 +1007,62 @@ private struct ZoomingCanvas: NSViewRepresentable {
(scroll.documentView as? NSHostingView<TappableCanvas>)?.rootView = TappableCanvas(layout: layout, focus: focus, tap: tap)
}
}
#else
private final class FittingScrollView: UIScrollView, UIScrollViewDelegate {
let host: UIHostingController<TappableCanvas>
private var fitted = false
init(_ canvas: TappableCanvas, size: CGSize) {
host = UIHostingController(rootView: canvas)
super.init(frame: .zero)
host.view.backgroundColor = .clear
host.view.frame = CGRect(origin: .zero, size: size)
addSubview(host.view)
contentSize = size
delegate = self
minimumZoomScale = 0.25
maximumZoomScale = 6
}
required init?(coder: NSCoder) {
fatalError("init(coder:) is not supported")
}
override func layoutSubviews() {
super.layoutSubviews()
if !fitted, bounds.width > 0, bounds.height > 0, host.view.bounds.width > 0 {
fitted = true
zoomScale = min(2, bounds.width / host.view.bounds.width, bounds.height / host.view.bounds.height)
}
center()
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
host.view
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
center()
}
private func center() {
let x = max(0, (bounds.width - contentSize.width) / 2)
let y = max(0, (bounds.height - contentSize.height) / 2)
contentInset = UIEdgeInsets(top: y, left: x, bottom: y, right: x)
}
}
private struct ZoomingCanvas: UIViewRepresentable {
let layout: BoxLayout
let focus: BoxFocus?
let tap: (String?) -> Void
func makeUIView(context: Context) -> FittingScrollView {
FittingScrollView(TappableCanvas(layout: layout, focus: focus, tap: tap), size: layout.size)
}
func updateUIView(_ scroll: FittingScrollView, context: Context) {
scroll.host.rootView = TappableCanvas(layout: layout, focus: focus, tap: tap)
}
}
#endif