SwiftyGroup
2.21K subscribers
165 photos
1 video
149 files
175 links
Собираю единомышленников для совместного изучения Swift, подготовки к собеседованиям и прокачивания скилов:)

Чат группы:
https://t.me/swiftygroup
@swiftygroup

Все самое интересное:
https://boosty.to/buik

Админ:
@VladimirBuik
Download Telegram
Пятничный квиз📣

class Person: NSObject {
var name: String
init(name: String) { self.name = name }
override var description: String { name }
}

var teamA: [Person] = [
Person(name: "Alice"),
Person(name: "Bob"),
Person(name: "Charlie")
]

var teamB = teamA
teamA[0].name = "Diana"
teamA.removeLast()
print(teamB)
Please open Telegram to view this post
VIEW IN TELEGRAM
18831👍1
SwiftyGroup
Что выведет принт?
Почему так происходит?

• Array в Swift — структура (value type),
значит сам массив копируется.

• Но внутри массива лежат объекты класса —
а класс это reference type (копируется только ссылка на объект).

• Когда мы делаем var teamB = teamA,
создаётся новый массив, но оба массива содержат ссылки на одни и те же объекты.

• Изменяя teamA[0].name,
мы изменяем сам объект, а не массив —
поэтому изменения видны и в teamB.

• А вот операция removeLast() влияет только на сам массив teamA,
поэтому teamB по-прежнему хранит все три элемента.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍188
👆 UIKit 26 — фича №9

В iOS 26 UINavigationController получил новый жест,
который делает возврат назад намного естественнее.


🆕 interactiveContentPopGestureRecognizer

Раньше жест “свайп назад” работал только от левого края экрана.
Теперь появился новый распознаватель — interactiveContentPopGestureRecognizer,
который позволяет начинать свайп из любой точки контента, а не только с границы.

Пример использования

let gesture = navigationController?.interactiveContentPopGestureRecognizer
myScrollView.panGestureRecognizer.require(toFail: gesture!)

или просто активировать его вручную:

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.interactiveContentPopGestureRecognizer.isEnabled = true
}


💡 Что это даёт
• Жест “назад” становится доступным по всему экрану,
даже если контент перехватывает касания.
• Больше не нужны костыли с кастомными pan-распознавателями.
• Переходы становятся естественнее и плавнее, но при этом
всё ещё остаются интерактивными и работают с анимациями UINavigationController.


📱 Итого: теперь свайп-назад работает так, как многие всегда хотели —
в любом месте экрана, без попадания строго в край и без конфликтов со scrollView.


#ios26
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
📱 Combine — тайное оружие iOS-разработчика, о котором все слышали, но мало кто реально понимает

На Хабре вышла большая статья от Банки.ру, где Combine объясняют не как «ещё один фреймворк», а как фундаментальную модель работы с данными в iOS. И реально раскладывают всё по полочкам.

🔍 Что важно понять про Combine
• Это не просто Publisher и Subscriber — это целая реактивная модель.
• SwiftUI под капотом живёт на Combine.
@Published, ObservableObject, цепочки операторов — всё это работает как поток данных, а не как «просто переменная».
• Combine заставляет думать декларативно: данные текут → UI реагирует.
• Автор показывает, как это работает на самом низком уровне — даже создаёт свой мини-Combine.

⚙️ Почему это полезно
• Лучше понимаешь, что именно делает SwiftUI, когда ты меняешь состояние.
• Перестаёшь бояться операторов и подписок.
• Видишь, где Combine силён, а где — проще использовать async/await.
• Понимаешь, как писать код, который не разваливается от гонок состояний.

🚀 Что это меняет
• В продакшене Combine остаётся важным инструментом — особенно в больших проектах.
• Async/await не убил реактивный подход — наоборот, он отлично его дополняет.
• Знание Combine = сильнее понимание архитектуры и потоков данных.

🗣️ Вывод
Combine — это не модный фреймворк, а фундамент. Если понимать его «мозги», SwiftUI и реактивный код становятся намного проще.

Читать статью →
👍8🔥71
🧩 UIKit 26 — фича №10

Сегодня разберём одно из самых заметных обновлений для iPad iOS 26 —
новые возможности работы с системным меню-баром на iPadOS.

В iPadOS теперь есть полноценное меню как на macOS: File, Edit, View, Find…
И с приходом iOS 26 разработчики наконец могут гибко управлять этим меню:
добавлять свои пункты, подменять системные, скрывать ненужные и менять структуру прямо в рантайме —
без хаков, без обходных путей и без пересборки всего меню целиком.


🆕 Новые идентификаторы меню

UIMenu.Identifier.newItem
UIMenu.Identifier.findPanel

• .newItem пришёл на замену устаревшему .newScene.
• .findPanel — отдельная группа команд для поиска (Find, Replace, Search Options).

Это пригодится, когда вы хотите кастомизировать системные меню, но не переписывать структуру полностью.


🛠 Новые методы UIMenuBuilder

Теперь можно динамически модифицировать меню по отдельным элементам.

🔄 Замена

builder.replace(menu: .file, with: newMenu)
builder.replace(action: .paste, with: newPasteAction)
builder.replace(command: "myCmd", propertyList: nil, with: newCommand)

Вставка

builder.insertElements([element], beforeMenu: .edit)
builder.insertElements([element], afterMenu: .view)
builder.insertElements([element], atStartOfMenu: .file)
builder.insertElements([element], atEndOfMenu: .file)

🗑 Удаление

builder.remove(action: .duplicate)
builder.remove(command: "customCommand", propertyList: nil)

Полный контроль над структурой без пересоздания меню — наконец-то нативно.

🧠 Когда это полезно
• скрыть/показать пункты меню в зависимости от состояния приложения
• выделять специфические команды (например, режим редактирования)
• подменять стандартные команды на свои
• динамически вставлять быстрые действия
• отключать определённые действия при отсутствии контекста

Раньше всё это делали через костыли, теперь же API официально поддерживает подобные сценарии.
3
👍1
Какой цвет выведет принт?
Anonymous Quiz
47%
Зеленый
53%
Красный
7👍4
UIKit 26 — фича №11

Сегодня разберём обновления UIButton.Configuration, которые Apple добавила в iOS 26.
Это две небольшие, но очень важные фичи, которые одновременно улучшают визуальную часть и дают более современное поведение кнопок.

🧊 1. Новые Liquid Glass-кнопки

UIKit получил готовые конфигурации кнопок в стиле Liquid Glass —
полупрозрачные, блестящие, с мягкими бликами и эффектом стекла.

Добавлены 4 новых статических метода:

UIButton.Configuration.glass()
UIButton.Configuration.clearGlass()
UIButton.Configuration.prominentGlass()
UIButton.Configuration.prominentClearGlass()


Как они отличаются?
• .glass() — стандартная стеклянная кнопка
• .clearGlass() — более прозрачная, менее акцентная
• .prominentGlass() — акцентная версия, похожа на .prominent стиль
• .prominentClearGlass() — акцентная, но с лёгкой прозрачностью

🔄 2. symbolContentTransition

Теперь UIButton.Configuration умеет анимировать смену SF Symbol
в кнопке автоматически, без вашего кода анимации.

Добавлено новое свойство:

var symbolContentTransition: UISymbolContentTransition? { get set }

Теперь всякий раз, когда вы меняете image:

button.configuration?.image = UIImage(systemName: "heart.fill")

UIKit сам сделает плавную анимацию
(замена, появление, масштабирование — в зависимости от выбранного transition).

🎬 Поддерживаемые переходы

UISymbolContentTransition(.replace)
UISymbolContentTransition(.scale)
UISymbolContentTransition(.reveal)

#ios26
🔥10👎1
Всем привет🍷
По реакциям вижу марафорн мой не особо заходит 😕, поэтому подготовил для вас перевод базовой статьи, чтобы загладить вину, сделал все красиво в Телеграфе, как советовали подписчики🙏.

Ковариантность и контравариантность в Swift
• Возвращаемые типы у функций/замыканий — ковариантны.
• Параметры функций/замыканий — контравариантны.
• Свои generic-типы — инвариантны, а стандартные коллекции Swift ведут себя «особенно» благодаря магии компилятора.

Подробное объяснение — тут:
https://telegra.ph/Kovariantnost-i-kontravariantnost-v-Swift-11-27

Всем пис!🙈
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1041👍11
🚨 Скидка 70% на все подписки Boosty и Tribute!

Решил сделать большую скидку — минус 70% на все виды подписок. Сейчас самое время залететь, потому что внутри уже лежит огромное количество материала, который я собираю каждый день.

Что получите по подписке:
🏴‍☠️ Записи реальных собеседований iOS
Вопросы уровня Middle/Senior, мои ответы, разборы ловушек, tricky-моменты, async/await, KVO, memory warnings, SOLID-антипаттерны и многое другое.
⚰️ Большая база задач
Комплексные Swift-задачи «что выведет», edge cases, сложные примеры, практические задачи, подробно разобранные решения.
💯 Гайды и шпаргалки
REST vs WebSocket, KVO, память, архитектура, работа с CoreData/SwiftData, RxSwift → Combine → async/await, Actors, UIView/SwiftUI тонкости.
😊 Переводы статей и документации
Популярные материалы с Medium/Dev/Reddit, а также переводы официальной Swift-доки.
👨‍🍳Фреймворки, лайфхаки и паттерны
Подборка библиотек, настройки проекта, примеры рефакторинга, «грязные» хаки, которыми мы все иногда пользуемся.
🎁 И ещё: доступ к закрытому чату, обновлениям, переводам, моим заметкам и всем новым материалам.

Скидка действует ограниченное время.
Если думали подписаться — сейчас лучший момент 💳

Boosty: 70% https://boosty.to/buik
Tribute: 70% https://t.me/tribute/app?startapp=ssYu
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥721111
🎨 UIKit 26 — фича №12

SF Symbols получили новые режимы рендеринга.
Теперь символы могут выглядеть ярче, объёмнее и “живее” — без кастомной графики.

🔹 1. Градиентный рендеринг

image = image.applyingSymbolConfiguration(
.init(colorRenderingMode: .gradient)
)

Символ автоматически получает мягкий системный градиент (в стиле iOS 26 / visionOS).

🔹 2. “Draw” режим

Символ выглядит как будто нарисован кистью:

image = image.applyingSymbolConfiguration(
.init(variableValueMode: .draw)
)

Полезно для декоративных UI, заметок, творчества.

🔹 3. Variable Value + Color mode

Теперь “живые” символы можно рендерить цветом:

image = image.applyingSymbolConfiguration(
.init(variableValueMode: .color)
)

Например — индикаторы (заряд, прогресс, температура).
65👍3
tab-bar-controller-tab-bar-minimize-behavior-demo.mp4
400.8 KB
🏷️ UIKit 26 — фича №13

Bottom Accessory в UITabBarController

В iOS 26 Apple впервые добавила официальный способ размещать плавающую панель над таббаром — как в Music или Podcasts.
Раньше все делали это костылями через additionalSafeAreaInsets и ручное добавление subviews.
Теперь есть нормальный API.

🆕 UITabAccessory + bottomAccessory

Чтобы добавить нижний аксессуар:

let accessory = UITabAccessory(contentView: customView)
tabBarController.bottomAccessory = accessory

А чтобы показать/скрыть с анимацией:

tabBarController.setBottomAccessory(accessory, animated: true)

Это может быть мини-плеер, панель состояния, быстрые действия — всё, что раньше приходилось “прибивать гвоздями”.


📦 Поведение таббара: сворачивание и расширение

В iOS 26 таббар умеет минимизироваться при скролле,
и bottom accessory тоже меняет состояние вместе с ним.

Режимы задаются:

tabBarController.tabBarMinimizeBehavior = .onScrollDown

Доступные варианты:
• .automatic — система сама решает
• .never — не сворачивать
• .onScrollDown — свернуть при скролле вниз
• .onScrollUp — свернуть при скролле вверх


🌐 Определение состояния аксессуара

UIKit вводит новый enum:

UITabAccessory.Environment

• .regular — аксессуар в полном размере
• .inline — компактный (в минимизированном таббаре)
• .none — не в среде таб-аксессуара
• .unspecified — ещё не отобразился

Состояние можно получить так:

traitCollection.tabAccessoryEnvironment


🧭 Новый layout guide

Чтобы правильно размещать контент над таббаром и аксессуаром:

let guide = tabBarController.contentLayoutGuide

Вью, прикреплённые к этому layout guide, автоматически адаптируются
к изменениям высоты таббара и состоянию аксессуара.

🔥 В итоге: теперь можно официально и красиво делать “мини-плееры”
и любые нижние панели поверх таббара — без костылей, багов и ручных отступов.
👍1031
🔍 ObservedObject vs @Observable в SwiftUI — в чём разница?

Если ты всё ещё используешь ObservedObject, самое время понять, почему новый @Observable меняет подход к управлению состоянием в SwiftUI.

Вот краткое и понятное сравнение 👇


🆕 1. @Observable (Swift 5.9 / SwiftData / iOS 17+)

Что это?
Новый макрос от Apple, который автоматически генерирует логику наблюдения без:
• ObservableObject
@Published
• objectWillChange

Преимущества:
• меньше шаблонного кода
• быстрее работает благодаря compile-time генерации
• более чистые модели данных

Пример:

@Observable
class UserSettings {
var username: String = "Puneet"
var isLoggedIn: Bool = false
}


🧓 2. ObservedObject (устаревающий, но всё ещё поддерживается)

Что это?
Старый механизм слежения за классами, реализующими ObservableObject.

Минусы:
• обязателен ObservableObject
• нужно ставить @Published на каждое поле
• больше кода
• наблюдение работает в рантайме → медленнее

Пример:

class UserSettings: ObservableObject {
@Published var username: String = "John"
@Published var isLoggedIn: Bool = false
}


💡 Вывод

➡️ @Observable — будущее SwiftUI: чище, быстрее, удобнее.
➡️ ObservedObject стоит использовать только для поддержки старых iOS.

#SwiftUI
👍8🔥432
🔥2
что будет результатом выполнения?
Anonymous Quiz
52%
«-824»
8%
«24»
32%
«42-8»
8%
«42»
👎166
В Swift приняли **SE-0493 — async в defer.

Раньше:
defer был строго синхронным.
Даже внутри async-функции нельзя было написать await в defer.

Из-за этого:
— асинхронный cleanup приходилось дублировать
— или делать Task { } внутри defer (который не ждёт выполнения)

Теперь:
в defer можно вызывать await, если окружающий контекст async.

func load() async {
await start()

defer {
await cleanup()
}

try await work()
}

Что важно:
— defer по-прежнему выполняется при выходе из scope
— порядок defer сохраняется (LIFO)
— await внутри defer ожидается, а не fire-and-forget
— работает только в async-контексте


https://github.com/swiftlang/swift-evolution/blob/main/proposals/0493-defer-async.md
Proposal принят и войдёт в Swift.
🔥266❤‍🔥21
Forwarded from Mobile VK Hub
This media is not supported in your browser
VIEW IN TELEGRAM
Конец года, и снова заканчиваются все подписки 😱

Узнали? Согласны? Не беда — мы как раз разыгрываем промокоды на год от Облака Mail и VK Музыки!

Условия участия простые:
🔹 подпишитесь на наш канал @mobilehubvk
🔹нажмите кнопку «Участвовать»
🔹 дождитесь 30 декабря — в этом посте мы выберем случайным образом 6 победителей

Информацию об организаторе, правилах и призах ищите по ссылке.

Удачи!
👎6👍31
#квиз последний в этом году🎅
Что выведет принт?
Anonymous Quiz
7%
SwiftUI
51%
Swift
42%
Ошибка
7👍33