Flutter UI组件插件swift_ui的使用

Flutter UI组件插件SwiftUI的使用


SwiftUI
由Flutter提供

项目简介

SwiftUI 是一个Flutter端的SwiftUI工具包。它旨在为开发者提供一个接近像素完美的SwiftUI体验。

使命

提供接近像素完美的SwiftUI体验在Flutter中

通过这个项目,我们希望展示以下几点:

  • 向开发者证明Flutter是iOS开发的一个绝佳选择。
  • 减轻Flutter框架团队在Cupertino方面的负担,让他们可以更专注于框架本身的发展。
  • 展示Flutter社区能够团结起来解决大型问题。

如何参与

克隆SwiftUI是一个庞大且持续的任务。项目需要所有可能的帮助。你既可以以技术手段也可以以非技术手段帮助这个项目。请查看贡献指南了解更多细节。


完整示例代码

import 'package:flutter/material.dart';
import 'package:swift_ui/swift_ui.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return const Scaffold(
      body: NavigationView(
        child: Center(
          child: NavigationBarTitle(
            "第三标题",
            child: Text("内容文本"),
          ),
        ),
      ),
    );
  }
}

class NavigationView extends StatefulWidget {
  static NavigationViewState of(BuildContext context) {
    return context.findAncestorStateOfType<NavigationViewState>()!;
  }

  const NavigationView({
    super.key,
    required this.child,
  });

  final Widget child;

  [@override](/user/override)
  State<NavigationView> createState() => NavigationViewState();
}

class NavigationViewState extends State<NavigationView> {
  String? title;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(
      children: [
        const SizedBox(height: 100),
        Container(
          height: 54,
          color: Colors.yellow,
          child: Center(
            // child: LateBoundBuilder(
            child: LateBoundBuild(
              builder: (context) {
                final title = NavigationView.of(context).title ?? "默认标题";
                return Text(title);
              },
            ),
          ),
        ),
        Expanded(
          child: widget.child,
        ),
      ],
    );
  }
}

class NavigationBarTitle extends StatefulWidget {
  const NavigationBarTitle(
    this.title, {
    super.key,
    this.child,
  });

  final String title;
  final Widget? child;

  [@override](/user/override)
  State<NavigationBarTitle> createState() => _NavigationBarTitleState();
}

class _NavigationBarTitleState extends State<NavigationBarTitle> {
  [@override](/user/override)
  void didChangeDependencies() {
    super.didChangeDependencies();

    NavigationView.of(context).title = widget.title;
  }

  [@override](/user/override)
  void didUpdateWidget(NavigationBarTitle oldWidget) {
    super.didUpdateWidget(oldWidget);

    NavigationView.of(context).title = widget.title;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return widget.child ?? const SizedBox();
  }
}

class LateBoundBuilder extends StatelessWidget {
  const LateBoundBuilder({
    super.key,
    required this.builder,
  });

  final WidgetBuilder builder;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, _) => builder(context));
  }
}

更多关于Flutter UI组件插件swift_ui的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter UI组件插件swift_ui的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,虽然原生的Swift UI是Apple为iOS开发提供的一套强大的UI框架,但它并不能直接在Flutter中使用。不过,Flutter提供了强大的插件系统和与原生代码交互的能力,允许你通过Platform Channels与原生iOS(使用Swift或Objective-C)或Android(使用Kotlin或Java)代码进行通信。

如果你想在Flutter应用中集成一些iOS原生UI组件,你可以创建一个自定义的Flutter插件。下面是一个简要的步骤指南和代码示例,展示如何创建一个简单的Flutter插件,该插件在iOS端使用Swift UI组件。

步骤 1: 创建Flutter插件

首先,你需要创建一个Flutter插件。你可以使用Flutter的命令行工具来生成插件的基本结构。

flutter create --template=plugin my_swift_ui_plugin

这将创建一个名为my_swift_ui_plugin的Flutter插件项目。

步骤 2: 配置iOS原生代码

进入插件的iOS目录(my_swift_ui_plugin/ios),并添加你的Swift UI组件。

MySwiftUIViewController.swift

ios/Classes目录下创建一个新的Swift文件,例如MySwiftUIViewController.swift,并添加以下内容:

import UIKit
import SwiftUI

class MySwiftUIViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let swiftUIView = MySwiftUIView()
        let hostingController = UIHostingController(rootView: swiftUIView)
        hostingController.view.frame = self.view.bounds
        self.addChild(hostingController)
        self.view.addSubview(hostingController.view)
        hostingController.didMove(toParent: self)
    }
}

struct MySwiftUIView: View {
    var body: some View {
        Text("Hello from Swift UI!")
            .padding()
            .background(Color.blue.opacity(0.1))
            .cornerRadius(10)
    }
}

步骤 3: 配置Flutter MethodChannel

ios/Classes/MySwiftUiPlugin.swift文件中,设置Platform Channel来与Flutter进行通信。

import Flutter

public class MySwiftUiPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(name: "my_swift_ui_plugin", binaryMessenger: registrar.messenger())
    let instance = MySwiftUiPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "presentSwiftUI":
      let controller = UIApplication.shared.keyWindow?.rootViewController
      if let navController = controller as? UINavigationController {
        let swiftUIViewController = MySwiftUIViewController()
        navController.pushViewController(swiftUIViewController, animated: true)
      } else if let viewController = controller {
        let navController = UINavigationController(rootViewController: viewController)
        let swiftUIViewController = MySwiftUIViewController()
        navController.pushViewController(swiftUIViewController, animated: true)
        UIApplication.shared.keyWindow?.rootViewController = navController
      }
      result(true)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
}

步骤 4: 在Flutter中使用插件

现在,你可以在Flutter项目中调用这个插件。首先,在Flutter项目的pubspec.yaml文件中添加你的插件依赖:

dependencies:
  flutter:
    sdk: flutter
  my_swift_ui_plugin:
    path: ../my_swift_ui_plugin

然后,在你的Flutter组件中调用插件的方法:

import 'package:flutter/material.dart';
import 'package:my_swift_ui_plugin/my_swift_ui_plugin.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Swift UI Plugin Demo'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              bool result = await MySwiftUiPlugin.presentSwiftUI();
              if (result) {
                print('Swift UI presented successfully');
              }
            },
            child: Text('Present Swift UI'),
          ),
        ),
      ),
    );
  }
}

注意:MySwiftUiPlugin.presentSwiftUI()方法需要你在插件的Dart代码中定义,它只是一个简单的封装来调用Platform Channel。

Dart端插件代码

my_swift_ui_plugin/lib/my_swift_ui_plugin.dart中,添加以下代码:

import 'dart:async';

import 'package:flutter/services.dart';

class MySwiftUiPlugin {
  static const MethodChannel _channel = const MethodChannel('my_swift_ui_plugin');

  static Future<bool> presentSwiftUI() async {
    final bool result = await _channel.invokeMethod('presentSwiftUI');
    return result;
  }
}

这样,你就完成了一个简单的Flutter插件,它可以在iOS端展示一个Swift UI组件。这个示例展示了如何通过Platform Channels在Flutter和原生iOS代码之间进行通信。

回到顶部