mirror of
https://github.com/shadowsocks/ShadowsocksX-NG.git
synced 2026-11-08 17:54:50 +00:00
68 lines
2.4 KiB
Swift
68 lines
2.4 KiB
Swift
import AppKit
|
|
import SwiftUI
|
|
|
|
/// 原生分栏只设置一次初始宽度,后续更新保留用户拖动的位置。
|
|
struct DiagnosticsLogSplitView<Logs: View, Details: View>: NSViewControllerRepresentable {
|
|
@ViewBuilder let logs: Logs
|
|
@ViewBuilder let details: Details
|
|
|
|
func makeNSViewController(context: Context) -> Controller {
|
|
Controller(logs: logs, details: details)
|
|
}
|
|
|
|
func updateNSViewController(_ controller: Controller, context: Context) {
|
|
controller.logs.rootView = logs
|
|
controller.details.rootView = details
|
|
// 离开 SwiftUI 的尺寸试算与更新事务后,按实际分栏宽度定位。
|
|
DispatchQueue.main.async { [weak controller] in
|
|
controller?.initializeWidth()
|
|
}
|
|
}
|
|
|
|
func sizeThatFits(
|
|
_ proposal: ProposedViewSize, nsViewController: Controller, context: Context
|
|
) -> CGSize? {
|
|
proposal.replacingUnspecifiedDimensions(by: CGSize(width: 740, height: 300))
|
|
}
|
|
|
|
final class Controller: NSSplitViewController {
|
|
let logs: NSHostingController<Logs>
|
|
let details: NSHostingController<Details>
|
|
private var initializedWidth = false
|
|
|
|
init(logs: Logs, details: Details) {
|
|
self.logs = NSHostingController(rootView: logs)
|
|
self.details = NSHostingController(rootView: details)
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) { fatalError("NSViewController 不走 storyboard 初始化") }
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
splitView.isVertical = true
|
|
splitView.dividerStyle = .thin
|
|
let logItem = NSSplitViewItem(viewController: logs)
|
|
logItem.minimumThickness = 520
|
|
let detailItem = NSSplitViewItem(viewController: details)
|
|
detailItem.minimumThickness = 180
|
|
// 高于日志栏默认的 250、低于拖动的 490,窗口缩放优先调整日志栏。
|
|
detailItem.holdingPriority = NSLayoutConstraint.Priority(260)
|
|
addSplitViewItem(logItem)
|
|
addSplitViewItem(detailItem)
|
|
}
|
|
|
|
func initializeWidth() {
|
|
guard !initializedWidth, view.window != nil,
|
|
splitView.bounds.width >= 700 + splitView.dividerThickness
|
|
else { return }
|
|
initializedWidth = true
|
|
splitView.layoutSubtreeIfNeeded()
|
|
splitView.setPosition(
|
|
splitView.bounds.width - splitView.dividerThickness - 220, ofDividerAt: 0)
|
|
splitView.layoutSubtreeIfNeeded()
|
|
}
|
|
}
|
|
}
|