Sobes.tech
Middle

Jak Flutter dostosowuje się do systemu operacyjnego iOS?

sobes.tech AI

Odpowiedź od AI

Flutter używa silnika Skia do renderowania interfejsu użytkownika, który bezpośrednio współpracuje z GPU. Nie używa natywnych komponentów iOS (przycisków, przewijaków itp.). Ich wygląd i zachowanie są imitowane przez widżety Flutter stylizowane zgodnie z Human Interface Guidelines.

Na przykład, do tworzenia przycisku w stylu iOS używa się CupertinoButton:

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

class MyCupertinoButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoButton(
      child: Text('Нажми меня'),
      onPressed: () {
        // Akcja po naciśnięciu
      },
    );
  }
}

Flutter komunikuje się z natywnymi API za pomocą swoich pluginów, korzystając z kanałów platformowych (Platform Channels). Pozwala to wywołać natywny kod iOS z Dart i odwrotnie.

import 'package:flutter/services.dart';

class NativeApi {
  static const platform = MethodChannel('com.example.myapp/battery'); // Nazwa kanału

  Future<String> getBatteryLevel() async {
    try {
      final String result = await platform.invokeMethod('getBatteryLevel'); // Wywołanie natywnej metody
      return 'Poziom naładowania baterii: $result%.';
    } on PlatformException catch (e) {
      return "Nie udało się pobrać poziomu baterii: '${e.message}'.";
    }
  }
}

Po stronie iOS, natywny kod obsługuje wywołania przez MethodChannel.

// Kod Swift w projekcie iOS
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    let batteryChannel = FlutterMethodChannel(name: "com.example.myapp/battery",
                                              binaryMessenger: controller.binaryMessenger)
    batteryChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
      guard call.method == "getBatteryLevel" else {
        result(FlutterMethodNotImplemented)
        return
      }
      self.receiveBatteryLevel(result: result)
    })

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  private func receiveBatteryLevel(result: FlutterResult) {
    let device = UIDevice.current
    device.isBatteryMonitoringEnabled = true
    if device.batteryState == .unknown {
      result(FlutterError(code: "UNAVAILABLE",
                          message: "Poziom baterii niedostępny.",
                          details: nil))
    } else {
      result(Int(device.batteryLevel * 100))
    }
  }
}

Aby dostosować projekt, używa się widżetów z biblioteki cupertino, które naśladują styl iOS. Dostęp do funkcji specyficznych dla iOS jest również realizowany przez pluginy. Kompilacja aplikacji na iOS odbywa się przez Xcode. Flutter generuje projekt iOS, który następnie jest kompilowany do natywnego pliku wykonywalnego (.ipa).