我能够使用一种解决方法来解决这个问题。 UIKit/Catalyst 本身不提供任何方法来做到这一点。但是我可以在这篇文章中使用第二种方法大纲
如何从 Mac Catalyst 应用程序访问 AppKit API
https://betterprogramming.pub/how-to-access-the-appkit-api-from-mac-catalyst-apps-2184527020b5
我使用了第二种方法而不是第一种,因为第一种似乎是私有 API(我可能是错的)并且会在 App Store 中被拒绝。使用插件包并在其上调用方法的第二种方法对我来说效果很好。通过这种方式,我不仅能够执行缩放,还能够执行其他 MacOS Appkit 功能,例如监听键盘、鼠标滚动、悬停检测等。
创建插件包后,这是我在插件中的代码:
插件.swift:
import Foundation
@objc(Plugin)
protocol Plugin: NSObjectProtocol {
init()
func toggleZoom()
func macOSStartupStuff()
}
MacPlugin.swift:
import AppKit
class MacPlugin: NSObject, Plugin {
required override init() {}
func macOSStartupStuff() {
NSApplication.shared.windows.forEach({
$0.titlebarAppearsTransparent = true
$0.titleVisibility = .hidden
$0.backgroundColor = .clear
($0.contentView?.superview?.allSubviews.first(where: { String(describing: type(of: $0)).hasSuffix("TitlebarDecorationView") }))?.alphaValue = 0
})
}
func toggleZoom(){
NSApplication.shared.windows.forEach({
$0.performZoom(nil)
})
}
}
extension NSView {
var allSubviews: [NSView] {
return subviews.flatMap { [$0] + $0.allSubviews }
}
}
然后我从我的 iOS 应用代码中调用它。这会在顶部添加一个透明视图,双击调用插件代码以切换缩放。
请注意,您必须从 viewDidAppear 或在窗口已初始化和呈现时的某个地方调用它。否则将无法正常工作。
#if os(OSX) || os(macOS) || targetEnvironment(macCatalyst)
@objc func zoomTapped(){
plugin?.toggleZoom()
}
var pluginWasLoaded = false
lazy var plugin : Plugin? = {
pluginWasLoaded = true
if let window = (UIApplication.shared.delegate as? AppDelegate)?.window {
let transparentTitleBarForDoubleClick = UIView(frame: .zero)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(zoomTapped))
tapGesture.numberOfTapsRequired = 2
transparentTitleBarForDoubleClick.addGestureRecognizer(tapGesture)
transparentTitleBarForDoubleClick.isUserInteractionEnabled = true
transparentTitleBarForDoubleClick.backgroundColor = .clear
transparentTitleBarForDoubleClick.translatesAutoresizingMaskIntoConstraints = false
window.addSubview(transparentTitleBarForDoubleClick)
window.bringSubviewToFront(transparentTitleBarForDoubleClick)
window.addConstraints([
NSLayoutConstraint(item: transparentTitleBarForDoubleClick, attribute: .leading, relatedBy: .equal, toItem: window, attribute: .leading, multiplier: 1, constant: 0),
NSLayoutConstraint(item: transparentTitleBarForDoubleClick, attribute: .top, relatedBy: .equal, toItem: window, attribute: .top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: transparentTitleBarForDoubleClick, attribute: .trailing, relatedBy: .equal, toItem: window, attribute: .trailing, multiplier: 1, constant: 0),
transparentTitleBarForDoubleClick.bottomAnchor.constraint(equalTo: window.safeTopAnchor)
])
window.layoutIfNeeded()
}
guard let bundleURL = Bundle.main.builtInPlugInsURL?.appendingPathComponent("MacPlugin.bundle") else { return nil }
guard let bundle = Bundle(url: bundleURL) else { return nil }
guard let pluginClass = bundle.classNamed("MacPlugin.MacPlugin") as? Plugin.Type else { return nil }
return pluginClass.init()
}()
#endif
从 viewDidAppear 调用它:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
#if os(OSX) || os(macOS) || targetEnvironment(macCatalyst)
if !Singleton.shared.pluginWasLoaded {
Singleton.shared.plugin?.macOSStartupStuff()
}
#endif
}