我想为 macOS 创建一个嵌入 PDFThumbnailView 的 PDFView。 PDFThumbnailView 应垂直,位于 PDFView 的右侧。我希望两个视图都位于一个 NSViewRepresentable 内。但是,我不太熟悉 UIKit 及其约束,我能做的最好的事情就是使 PDFThumbnailView 与 PDFView 重叠。如何使 PDFView 和 PDFThumbnailView 分开,这样它们就不会重叠?这是代码:
struct PDFViewWrapper: NSViewRepresentable {
let pdfView = PDFView()
@Binding var pdfDisplay: Int
func makeNSView(context: Context) -> PDFView {
let fileURL = FileManagerClient.shared.getDocumentsDirectory().appendingPathComponent("example.PDF")
let pdfDocument = PDFDocument(url: fileURL)
///
let thumbnailView = PDFThumbnailView()
thumbnailView.translatesAutoresizingMaskIntoConstraints = false
pdfView.addSubview(thumbnailView)
thumbnailView.pdfView = pdfView
NSLayoutConstraint.activate(
[
thumbnailView.leadingAnchor.constraint(equalTo: pdfView.safeAreaLayoutGuide.leadingAnchor),
thumbnailView.topAnchor.constraint(equalTo: pdfView.safeAreaLayoutGuide.topAnchor),
thumbnailView.bottomAnchor.constraint(equalTo: pdfView.safeAreaLayoutGuide.bottomAnchor),
thumbnailView.widthAnchor.constraint(equalToConstant: 80),
]
)
thumbnailView.thumbnailSize = CGSize(width: 100, height: 100)
thumbnailView.backgroundColor = .placeholderTextColor
///
pdfView.document = pdfDocument
pdfView.autoScales = true
pdfView.displayMode = PDFDisplayMode(rawValue: pdfDisplay) ?? .singlePageContinuous
return pdfView
}
func updateNSView(_ uiView: PDFView, context: Context) {}
}
NSStackView
。我在代码中添加了注释以进行一些解释。
struct PDFViewWrapper: NSViewRepresentable {
let url: URL
let pdfDisplay: PDFDisplayMode
@MainActor
class Coordinator {
// instead of initialising these in the NSViewRepresentable,
// do the initialisation in the Coordinator, so they don't get
// needlessly reinitislied every view update
let pdfView = PDFView()
let pdfThumbnails = PDFThumbnailView()
}
func makeNSView(context: Context) -> NSView {
let pdfDocument = PDFDocument(url: url)
context.coordinator.pdfThumbnails.thumbnailSize = CGSize(width: 100, height: 100)
context.coordinator.pdfThumbnails.backgroundColor = .placeholderTextColor
context.coordinator.pdfThumbnails.pdfView = context.coordinator.pdfView
context.coordinator.pdfView.document = pdfDocument
context.coordinator.pdfView.autoScales = true
context.coordinator.pdfView.displayMode = pdfDisplay
let stackView = NSStackView(views: [context.coordinator.pdfThumbnails, context.coordinator.pdfView])
stackView.orientation = .horizontal
// the only constraint you need here is for the width of the thumbnails
// the stack view handles the rest for you
NSLayoutConstraint.activate([
context.coordinator.pdfThumbnails.widthAnchor.constraint(equalToConstant: 100)
])
return stackView
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func updateNSView(_ uiView: NSView, context: Context) {
// this is where you update the AppKit views to respond to a SwiftUI view update
if context.coordinator.pdfView.document?.documentURL != url {
context.coordinator.pdfView.document = PDFDocument(url: url)
}
context.coordinator.pdfView.displayMode = pdfDisplay
}
}