Build Status Platforms Discord

NSUI

没有条件编译的 AppKit 和 UIKit

AppKit 和 UIKit 中,即使是源代码兼容的类之间也存在一些细微的差异,这让每个人都感到头疼。我受到了 Nick Lockwood 的启发,将其制作成一个包。

如有疑问,UIKit 优先。这能让大多数人感到熟悉。

集成

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/mattmassicotte/nsui")
]

使用

// not only does this import the NSUI package, but it also will correctly make either AppKit or UIKit accessible depending on the build target platform.
import NSUI

// Make use of the cross-platform wrappers
let textView = NSUITextView()

在某些情况下,有必要为函数、访问器或初始化器提供跨平台包装器。这些考虑了类型差异,包括仅在可选性方面存在差异的情况。

// SwiftUI
Color(nsuiColor: NSUIColor)
Image(nsuiImage: NSUIImage)
NSUIControlActiveState

// AppKit/UIKit
NSUIFont.init(nsuiDescriptor:, size:)
NSUIFontDescriptor.nsuiWithSymbolicTraits(_:)
NSUITextView.nsuiLayoutManager
NSUITextView.nsuiSelectedRange

NSUI 还包括 NSUIViewRepresentableNSUIViewControllerRepresentable 来包装你的自定义视图子类。

类型

所有类型及其对应的 UIKit & AppKit 都定义在 Aliases.swift 文件中。该文件仅定义与适当平台对应的 NSUI 类型。

以下是 NSUI 当前支持的类型列表

NSUIActivityIndicatorView
NSUIApplication
NSUIApplicationDelegate
NSUIApplicationDelegateAdaptor
NSUIBezierPath

// Collection Views
NSUICollectionDataSource
NSUICollectionView
NSUICollectionViewItem
NSUICollectionViewDelegate
NSUICollectionViewLayout
NSUICollectionViewFlowLayout
NSUICollectionViewLayoutAttributes
NSUICollectionViewDelegateFlowLayout

NSUIButton
NSUIColor
NSUIEdgeInsets
NSUIFont
NSUIFontDescriptor
NSUIHostingController
NSUIImage
NSUILongPressGestureRecognizer
NSUINib
NSUIPasteboard
NSUIResponder
NSUIStackView
NSUIStoryboard
NSUITapGestureRecognizer
NSUITextField
NSUITextFieldDelegate
NSUITextView
NSUIViewController
NSUIWorkspace

如果您正在寻找事件键映射,特别是 UIKeyboardHIDUsageUIKeyModifierFlags,请查看 KeyCodes

约定

NSUI 不是一个用于取代 UIKit 和 AppKit 的多平台框架。如上所述,NSUI 坚持认为 UIKit 的 API 是首选。但是,在某些情况下,AppKit 和 UIKit 非常相似。

例如,NSProgressIndicatorUIActivityIndicator 类。要启动旋转的指示器视图,你需要对 UIKit 执行 startAnimating(),对 AppKit 执行 startAnimation(sender:)

为了弥合这种细微的差异,在 Views.swift 文件中创建了一个桥接函数,如下所示

extension NSUIActivityIndicator {
    public func startAnimating() {
        self.startAnimation(nil)
    }
    
    public func stopAnimating() {
        self.stopAnimation(nil)
    }
}

此扩展包装在 #if canImport(AppKit) 中,并为 AppKit 类提供 UIKit 的功能等效项。

增强 NSUI

如果你需要增强 NSUI,请遵循以下准则

  1. 检查你需要的类型是否已在 Aliases.swift 文件中定义。
  2. 如果你的类型需要桥接函数,请在专用文件中定义它们。
  3. 优先考虑 UIKit 实现,除非类型不匹配阻止它。

替代方案

贡献和协作

我很乐意听到你的声音! Issues 或 Pull Requests 都很棒。 一个 Discord 服务器 也可用于实时帮助,但我强烈倾向于以文档的形式回答问题。

我更喜欢协作,并且很乐意找到与你合作的方式,如果你有类似的项目。

我更喜欢使用制表符进行缩进,以提高可访问性。 但是,我宁愿你使用你想要的系统并提出 PR,也不愿因为空格而犹豫不决。

通过参与这个项目,你同意遵守贡献者行为准则