@nativescript/swift-ui
SwiftUI for NativeScript
npm i --save @nativescript/swift-ui

@nativescript/swift-ui

使用 NativeScript 与 SwiftUI。

内容

安装

npm install @nativescript/swift-ui

注意:您至少需要针对 iOS 13。例如,您可以在您的 App_Resources/iOS/build.xcconfig 中添加此行

IPHONEOS_DEPLOYMENT_TARGET = 13.0

注意:如果您想在 SwiftUI 中使用 NativeScriptView,则应针对至少 14.0。

使用

SwiftUI Source Files Example

1. 创建您的 SwiftUI 视图

这可以是您想要创建的任何 SwiftUI 视图。

import SwiftUI

struct SampleView: View {

var body: some View {
VStack {
Text("Hello World")
.padding()
}
}
}

2. 创建您的 SwiftUI 视图提供者

这将准备您的 SwiftUI 以进行双向数据绑定到 NativeScript,并遵循插件 SwiftUIProvider 协议以标准化所有 SwiftUI 绑定。

import SwiftUI

@objc
class SampleViewProvider: UIViewController, SwiftUIProvider {

// MARK: INIT

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

required public init() {
super.init(nibName: nil, bundle: nil)
}

public override func viewDidLoad() {
super.viewDidLoad()
setupSwiftUIView(content: swiftUIView)
}

// MARK: PRIVATE

private var swiftUIView = SampleView()

/// Receive data from NativeScript
func updateData(data: NSDictionary) {
// can be empty
}

/// Allow sending of data to NativeScript
var onEvent: ((NSDictionary) -> ())?
}

3. 使用标识符注册 SwiftUI 并在标记中使用它

这可以在引导文件(通常是 app.tsmain.ts)或任何需要它的视图组件中完成。

核心

import { 
registerSwiftUI,
UIDataDriver
} from "@nativescript/swift-ui";

// A. You can generate types for your own Swift Provider with 'ns typings ios'
// B. Otherwise you can ignore by declaring the class name you know you provided
declare const SampleViewProvider: any;

registerSwiftUI("sampleView", (view) =>
new UIDataDriver(SampleViewProvider.alloc().init(), view)
);

registerSwiftUI("barChart", (view) =>
new UIDataDriver(BarChartProvider.alloc().init(), view)
);

然后按照以下方式将其插入任何布局中

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page" xmlns:sw="@nativescript/swift-ui">
<StackLayout>
<sw:SwiftUI swiftId="sampleView" height="150" />
</StackLayout>
</Page>

生成类型

  1. 要为您的 SwiftUI 代码生成类型,请运行 ns typings ios

  2. typings/x86_64 中找到 objc!nsswiftsupport.d.ts 文件,并在 references.d.ts 中引用它。

SwiftUI 与 Angular

注册 SwiftUI

import { registerElement } from '@nativescript/angular'
import { SwiftUI } from '@nativescript/swift-ui'

registerElement('SwiftUI', () => SwiftUI)

registerSwiftUI("sampleView", (view) =>
new UIDataDriver(SampleViewProvider.alloc().init(), view)
);
registerSwiftUI("barChart", (view) =>
new UIDataDriver(BarChartProvider.alloc().init(), view)
);

现在它可以在任何 Angular 组件中使用,例如

<StackLayout class="p-20">
<SwiftUI swiftId="sampleView" height="150"></SwiftUI>
</StackLayout>

SwiftUI 与 Vue

注册 SwiftUI

registerElement("SwiftUIView", ()=> require("@nativescript/swift-ui").SwiftUI)

registerSwiftUI("sampleView", (view) =>
new UIDataDriver(SampleViewProvider.alloc().init(), view)
);
registerSwiftUI("barChart", (view) =>
new UIDataDriver(BarChartProvider.alloc().init(), view)
);

然后按照以下方式在标记中使用它

<StackLayout>

<SwiftUIView swiftId="sampleView" height="200" />
<SwiftUIView height="500" swiftId="barChart" margin="30" />

</StackLayout>

SwiftUI 与 React

注册 SwiftUI

registerSwiftUI("sampleView", (view) =>
new UIDataDriver(SampleViewProvider.alloc().init(), view)
);

registerSwiftUI("barChart", (view) =>
new UIDataDriver(BarChartProvider.alloc().init(), view)
);

interface SwiftUIViewAttributes extends ViewAttributes{
swiftId: string
}

declare global {
module JSX {
interface IntrinsicElements {

swiftUIView: NativeScriptProps<SwiftUIViewAttributes, SwiftUI>
}
}
}

registerElement("swiftUIView", ()=> require("@nativescript/swift-ui").SwiftUI)

然后按照以下方式在标记中使用它

<stackLayout>

<swiftUIView swiftId="sampleView" height="200" />
<swiftUIView height="500" swiftId="barChart" margin="30" />

</stackLayout>

打开多个场景

当为您的 NativeScript 应用程序设置 SwiftUI 应用生命周期时(默认为 visionOS 开发),您可以在 Info.plist 中使用以下内容启用多个场景

<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationPreferredDefaultSceneSessionRole</key>
<string>UIWindowSceneSessionRoleApplication</string>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict/>
</dict>

现在您可以使用 WindowManager(用于使用标准窗口)或 XR(用于使用沉浸式空间)与多个场景交互,例如

@main
struct NativeScriptApp: App {
@State private var immersionStyle: ImmersionStyle = .mixed

var body: some Scene {
NativeScriptMainWindow()

WindowGroup(id: "NeatView") {
NeatView()
}
.windowStyle(.plain)

ImmersiveSpace(id: "NeatImmersive") {
NeatImmersive()
}
.immersionStyle(selection: $immersionStyle, in: .mixed, .full)
}
}

您可以使用以下内容打开 WindowGroup

import { WindowManager } from "@nativescript/swift-ui";

WindowManager.getWindow("NeatView").open();
});

您可以使用以下内容打开 ImmersiveSpace

import { XR } from "@nativescript/swift-ui";

XR.requestSession("NeatImmersive");

您可以使用以下内容更新任何场景

import { WindowManager } from "@nativescript/swift-ui";

// Option A: inline
WindowManager.getWindow("NeatView").update({
title: 'Updated Title'
});

// Option B: reference
const neatView = WindowManager.getWindow("NeatView");

neatView.update({
title: 'Updated Title'
});

// Both options work with XR/Immersive Spaces as well, for example:
WindowManager.getWindow("NeatImmersive").update({
salutation: 'Hello World'
});

将上下文数据传递到场景

您可以使用 SwiftUI 中的 onReceive 修饰符来处理传递到您的窗口中的任何数据。

例如,每次调用 WindowManager.getWindow("Window_ID").update(...) 时,都会发送一个通知,可以捕获以处理数据

struct NeatView: View {
@State var context: NativeScriptWindowContext?

var body: some View {
ZStack {
// more neat views here
}.onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("NativeScriptWindowUpdate")), perform: { obj in
context = NativeScriptWindowFactory.shared.getContextForId(id: "NeatView")

let title = context!.data["title"] as! String

// use your updated title!
})
}
}

关闭窗口

WindowManager.getWindow("NeatView").close() 对于已打开的窗口将关闭它。

XR.endSession() 对于已打开的沉浸式空间将关闭它。

在 SwiftUI 中使用 NativeScriptView

您还可以在针对至少 iOS 14.0 时在 SwiftUI 中使用 NativeScript 视图布局和组件。

将此行添加到您的 App_Resources/iOS/build.xcconfig

IPHONEOS_DEPLOYMENT_TARGET = 14.0

您现在可以使用 id 注册多个 NativeScript 视图以供使用

import { SwiftUIManager } from '@nativescript/swift-ui';

SwiftUIManager.registerNativeScriptViews({
Video: SceneVideoComponent
});

这允许 SceneVideoComponent(一个 NativeScript 视图组件)在任何 SwiftUI 组件中使用

struct ContentView: View {

var body: some View {

ZStack {
NativeScriptView(id: "Video")
}
}
}

致谢

  • WindowManager 和 XR API 与 Callstack 团队一起建立。致敬:[Oskar Kwaśniewski](https://github.com/okwasniewski)。
Valor Software

NativeScript 由 Valor Software 欣然成为官方合作伙伴。我们自豪地提供关于 NativeScript 的指导、咨询和开发支持。

请联系 Valor 以获得帮助.

许可证

MIT