Sobes.tech
Back to questions
Middle
120
questionbank

Как Flutter адаптируется под операционную систему iOS?

Sobes Copilot

Get answers in real time

Answer from AI

sobes.tech AI

Флаттер использует движок Skia для рендеринга UI, который напрямую взаимодействует с GPU. Нативные компоненты iOS (кнопки, скроллы и т.д.) не используются. Их внешний вид и поведение имитируется виджетами Flutter, стилизованными под Human Interface Guidelines.

Например, для создания кнопки в стиле iOS используется 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: () {
        // Действие при нажатии
      },
    );
  }
}

Flutter взаимодействует с нативными API через свои плагины, используя платформенные каналы (Platform Channels). Это позволяет вызвать нативный код iOS из Dart и наоборот.

import 'package:flutter/services.dart';

class NativeApi {
  static const platform = MethodChannel('com.example.myapp/battery'); // Имя канала

  Future<String> getBatteryLevel() async {
    try {
      final String result = await platform.invokeMethod('getBatteryLevel'); // Вызов нативного метода
      return 'Уровень заряда батареи: $result%.';
    } on PlatformException catch (e) {
      return "Не удалось получить уровень заряда батареи: '${e.message}'.";
    }
  }
}

На стороне iOS, нативный код обрабатывает вызовы через MethodChannel.

// Swift код в 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: "Уровень заряда батареи недоступен.",
                          details: nil))
    } else {
      result(Int(device.batteryLevel * 100))
    }
  }
}

Для адаптации дизайна используются виджеты из библиотеки cupertino, имитирующие стиль iOS. Также доступ к специфическим функциям iOS осуществляется через плагины. Сборка приложения для iOS происходит через Xcode. Flutter генерирует iOS проект, который затем компилируется в нативный исполняемый файл (.ipa).</blockquote>