Ответ
Да, Material-виджеты работают на iOS, но это нарушает Apple Human Interface Guidelines (HIG) и создает неестественный пользовательский опыт для iOS-пользователей.
Пример Material-виджетов на iOS:
import 'package:flutter/material.dart';
MaterialApp(
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
title: Text('Material Design on iOS'),
actions: [
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {},
),
],
),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {},
child: Text('Material Button'),
),
Switch(
value: true,
onChanged: (bool value) {},
),
CircularProgressIndicator(),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
),
);
Проблемы Material Design на iOS:
-
Визуальные различия:
- Material использует shadows и elevation, iOS — flat design с blurs
- Разные типографика и spacing
- Material buttons имеют ripple effect, iOS — highlight
-
Навигационные паттерны:
- Material: hamburger menu, tabs сверху
- iOS: tab bar снизу, navigation bar сверху
- Разные жесты для возврата
-
Компоненты:
- Material dialogs vs. iOS alerts
- Material snackbars vs. iOS toasts
- Разные pickers и date selectors
Когда Material допустим на iOS:
// 1. Корпоративные/инструментальные приложения
Material(
elevation: 4,
borderRadius: BorderRadius.circular(8),
child: Container(
padding: EdgeInsets.all(16),
child: Text('Инструментальный интерфейс'),
),
);
// 2. Приложения с сильным брендингом
Theme(
data: ThemeData(
primaryColor: BrandColors.primary,
buttonTheme: ButtonThemeData(/* кастомный стиль */),
),
child: MaterialWidget(),
);
// 3. Прототипы и MVP
Лучшие практики для iOS-приложений:
// 1. Использование Cupertino-виджетов
CupertinoApp(
theme: CupertinoThemeData(
primaryColor: CupertinoColors.systemBlue,
),
home: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Нативный iOS'),
),
child: SafeArea(
child: ListView.builder(
itemBuilder: (context, index) => CupertinoListTile(
title: Text('Item $index'),
onTap: () {},
),
),
),
),
);
// 2. Адаптивные компоненты
Widget buildPlatformButton() {
if (Theme.of(context).platform == TargetPlatform.iOS) {
return CupertinoButton.filled(
onPressed: () {},
child: Text('iOS Button'),
);
} else {
return ElevatedButton(
onPressed: () {},
child: Text('Android Button'),
);
}
}
// 3. Пакет platform_widgets для упрощения
PlatformWidget(
android: (context) => MaterialWidget(),
ios: (context) => CupertinoWidget(),
);
Для production iOS-приложений рекомендуется использовать Cupertino-виджеты или реализовывать адаптивный UI, который соответствует ожиданиям пользователей каждой платформы.
Ответ 18+ 🔞
А, слушай, вот тебе история про Flutter и iOS, просто пиздец. Представь: ты делаешь приложение, всё красиво, Material Design, тени, кнопки с этими риппл-эффектами — красота, ёпта! А потом запускаешь на айфоне, и тут такое чувство, будто ты в Москву приехал в шортах и гавайской рубахе, когда на улице минус двадцать. Вроде живёшь, но все на тебя смотрят как на долбоёба.
Вот смотри, как это выглядит в коде:
import 'package:flutter/material.dart';
MaterialApp(
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
title: Text('Material Design on iOS'),
actions: [
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {},
),
],
),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () {},
child: Text('Material Button'),
),
Switch(
value: true,
onChanged: (bool value) {},
),
CircularProgressIndicator(),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
),
);
Всё работает, да. Но, блядь, это как зайти в дорогой итальянский ресторан и заказать пельмени с майонезом. Технически съедобно, но официант тебя возненавидит, а соседи по столу будут думать, что ты с другой планеты.
А теперь, почему это — пизда рулю на iOS:
-
Визуал — полный пиздец. У Material — тени, объём, эта материя. У iOS — всё плоское, с лёгкими размытиями, элегантное такое. Твои Material-кнопки на айфоне выглядят как жирные пончики на фоне хрустальных бокалов. Типографика другая, отступы другие. У Material кнопка при нажатии волнами расходится, а на iOS она просто подсвечивается. Пользователь айфона ткнет в твою кнопку и подумает: «Чё за хуйня, она что, сломалась?».
-
Навигация — ёперный театр. В Material-приложении меню часто слева, выдвижное, гамбургер. На iOS табы ВСЕГДА внизу, а навигационная панель — сверху. Жесты назад разные! На андроиде часто кнопка, на iOS — свайп с края. Твой пользователь будет пытаться свайпнуть, а него нихуя не получится, и он просто выбросит телефон в окно от бессилия. Доверия ебать ноль после такого.
-
Компоненты — вообще манда с ушами. Диалоговые окна, алерты, пикеры выбора даты — всё абсолютно другое. Material snackbar всплывает снизу, а iOS тост — обычно по центру. Поставишь не тот — и человек просто не поймёт, что ему приложение только что сообщило.
Хотя, справедливости ради, бывают случаи, когда можно. Ну, знаешь, как джинсы в театр — не очень, но если очень хочется, то можно.
// 1. Приложения-инструменты, корпоративные штуки.
// Ну там, складской учёт или графики для начальства. Там всем похуй на дизайн, лишь бы работало.
Material(
elevation: 4,
borderRadius: BorderRadius.circular(8),
child: Container(
padding: EdgeInsets.all(16),
child: Text('Инструментальный интерфейс'),
),
);
// 2. Сильный бренд. Если у тебя, например, весь фирменный стиль — это жёлтые треугольные кнопки.
// Тогда да, хуй с горы, делай как по бренд-буку, пусть даже на iOS.
// 3. Прототип или MVP, который надо вчера. Тут да, **да похуй**, лишь бы показать функционал.
Но если ты делаешь нормальное, продакшен-приложение для iOS, то делай так, чтобы не было стыдно:
// 1. Используй родные Cupertino-виджеты. Это как надеть костюм.
CupertinoApp(
theme: CupertinoThemeData(
primaryColor: CupertinoColors.systemBlue,
),
home: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Нативный iOS'),
),
child: SafeArea(
child: ListView.builder(
itemBuilder: (context, index) => CupertinoListTile(
title: Text('Item $index'),
onTap: () {},
),
),
),
),
);
// 2. Делай адаптивные штуки. Если на айфоне — показывай одну кнопку, если на андроиде — другую.
Widget buildPlatformButton() {
if (Theme.of(context).platform == TargetPlatform.iOS) {
return CupertinoButton.filled(
onPressed: () {},
child: Text('iOS Button'),
);
} else {
return ElevatedButton(
onPressed: () {},
child: Text('Android Button'),
);
}
}
// 3. Есть куча пакетов, которые упрощают эту жизнь. Не изобретай велосипед.
PlatformWidget(
android: (context) => MaterialWidget(),
ios: (context) => CupertinoWidget(),
);
Короче, суть в чём. Можно, конечно, запихнуть Material на iOS — технически-то всё запустится. Но это будет выглядеть как пидарас шерстяной на фоне остальных приложений. Пользователь откроет и сразу почувствует подозрение ебать, что что-то не так. А если он чувствует, что что-то не так, он удаляет приложение. Всё просто, ёпта. Хочешь, чтобы на iOS было хорошо — делай по-ихнему. Или хотя бы умно адаптируй. Иначе получится хитрая жопа, которая никому не нравится.