околоiOSный канал: cmd+B, cmd+R @ioscmdbcmdr Channel on Telegram

околоiOSный канал: cmd+B, cmd+R

@ioscmdbcmdr


iOS-разработка, мотивация, статьи, мемасики :)
___
Видео материалы, тестовые задания, информация по курсу:
YouTube-channel: https://www.youtube.com/c/cmdBcmdR
___
Дополнительные материалы + поддержка YouTube/Telegram канала
https://boosty.to/cmdbcmdr

околоiOSный канал: cmd+B, cmd+R (Russian)

Добро пожаловать в Telegram-канал \"околоiOSный канал: cmd+B, cmd+R\" (@"ioscmdbcmdr")! Если вы увлечены iOS-разработкой, мотивацией, статьями и мемами, то это место для вас! Канал предлагает широкий спектр контента – от видеоматериалов до тестовых заданий, а также информацию по курсу. Вы сможете найти интересные статьи, мотивирующие посты и даже забавные мемасики, чтобы поддерживать свой дух и энтузиазм.

Присоединяйтесь к нам, чтобы получить доступ к дополнительным материалам и получить поддержку YouTube/Telegram канала. Посетите наш YouTube-канал по ссылке: https://www.youtube.com/c/cmdBcmdR, где вы также найдете много полезного контента.

Не упустите возможность расширить свои знания и навыки в области iOS-разработки, а также поддержать вашу мотивацию вместе с \"околоiOSный канал: cmd+B, cmd+R\". Присоединяйтесь прямо сейчас!

околоiOSный канал: cmd+B, cmd+R

22 Jan, 09:19


А помните этот тупой вопрос на собеседовании:
"Назовите типы коллекций в Swift"

И нет, его не спрашивали, чтобы убедится, что джЮн изучил все необходимое.

Воздух начинал электризоваться, если ты называл кортежи(tuples). Начинались томные взгляды и вздохи.
КАК можно не знать, что в свифте только 3 типа коллекций: Массив, Словарь, Сет.

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

Пока я искал информацию, во многих статьях / видео, обнаруживал что onChange и onReceive относят к жизненному циклу.

Конечно, по факту, вааааааще по_уй куда они относятся, главное понимать как они работают. Но если заглянуть в документацию, то в разделе с жизненным циклом представления есть только 4(можно сказать 3) метода (см. изображение).

Методы жизненного цикла разобраны здесь.
onChange и onReceive - здесь.
Еще несколько опросов - здесь.

околоiOSный канал: cmd+B, cmd+R

20 Jan, 15:25


Тряпки, ноут, один стол...

Ведь 100% наберет больше просмотров, чем задачи из яндекса :)

Проверяем...

околоiOSный канал: cmd+B, cmd+R

20 Jan, 10:28


Закрепляй знания 💪

Теория без практики бесполезна!
Этот факт знает и понимает каждый.

Изучать небольшие темы (например, такие как жизненный цикл представления в SwiftUI) и сразу бросаться писать мини-проект - занятие хорошее, но максимально дорогостоящее.

Здесь на помощь приходят тесты. Тесты хороши тем, что вечером вы можете прочитать пост, а с утра проверить насколько хорошо вы усвоили материал.

Т.к. впереди много информации, которую необходимо изучить, а самое главное усвоить, в конце каждого поста я буду добавлять ссылку на телеграм-опросы по этой теме.

1-2 опроса будут появляться в околоiOSном чате, остальные опросы в чате-бусти.

Чтобы попасть в чат-бусти достаточно оформить минимальную подписку за 100р / месяц.

Для вас это может быть просто разлечение, а для меня отличная мотивация разбирать тему более подробно.

Как вы поняли по опросам, на бусти появился новый пост, посвященный методам жизненного цикла представлений.

Читать пост | Подписка за сотку

околоiOSный канал: cmd+B, cmd+R

20 Jan, 08:08


Заменим .sheet на .fullScreenCover
П.С. В принципе, все работает аналогично киту

околоiOSный канал: cmd+B, cmd+R

20 Jan, 07:34


Простенький опрос
Все как вы любите :)

околоiOSный канал: cmd+B, cmd+R

19 Jan, 11:20


Воскресенье - не помеха 🤓

Жизненный цикл представления решил разбить на 2 поста:

1. В первом посте рассказал о 3-х основных состояниях на основе имеющихся знаний о дереве представлений и графе.

2. Второй пост будет посвящен конкретным методам для взаимодействия с представлением.

После второго поста продолжим пилить 4-ое приложение.

Кажется, формируется структура курса :)

Читать пост | Подписка - лучший респект 🤘

околоiOSный канал: cmd+B, cmd+R

19 Jan, 07:07


Модификаторы становятся родителями для вью, к которой применяются (часть 2)

Теперь обратимся к документации.
Рассмотрим пример, указанный на странице протокола ViewModifier.


//Набор необходимых параметров/модификаторов
struct BorderedCaption: ViewModifier {
func body(content: Content) -> some View {
content
.font(.caption2)
.padding(10)
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(lineWidth: 1)
)
.foregroundColor(Color.blue)
}
}

//Рекомендумая реализация
extension View {
func borderedCaption() -> some View {
modifier(BorderedCaption())
}
}

//Применение
Text("Downtown Bus")
.borderedCaption()

Во-первых, body возвращает экземпляр, соответствующий протоколу View. Значит создается новая вьюха с новыми параметрами. BorderedCaption оборачивает контент исходной вью и становится для нее родительской.

Во-вторых, в расширении мы используем modifier.
Проваливаемся в документацию:
Use this modifier to combine a View and a ViewModifier, to create a new view.
Черный по русскому написано:
Используйте модификатор, чтобы объединить View и ViewModifier для создания новой вью.

Из всего, что было сказано выше, можно сделать вывод, что:
Модификаторы становятся родителями для вью, к которой применяются.

Как было сказано ранее, эта информация поможет нам с дальнейшим пониманием построения View Tree.

околоiOSный канал: cmd+B, cmd+R

19 Jan, 06:27


Модификаторы становятся родителями для вью, к которой применяются (часть 1)

Возвращаемся к опросу.
Понимание этой темы будет полезно позже, при более подробном рассмотрении View Tree и Attribute Graph.

Все что будет написано ниже - мои личные рассуждения. Т.к. со SwiftUI я не слишком знаком, некоторые утверждения могут быть спорны.

Начнем...

"Модификаторы становятся родителями для вью, к которой применяются" - скорее всего утверждение верное, потому что большинство модификаторов являются ViewBuilder'ами.
Могут быть исключения, поэтому сказать, что данное выражение подходит для ВСЕХ модификаторов, наверное нельзя.

Применение модификаторов схоже с потоком(stream) в реактивном программировании. На каждом шаге происходят различные преобразования с исходными данными.

Если не работали с реактивщиной, рассмотрим более простой и жизненный пример. Функции высшего порядка.

let array = [1, 2, 3, 4, 5]
array.map { $0 * 2 }
.filter { $0.isMultiple(of: 2) }
.reduce(0, +)

На каждом шаге мы оборачиваем данные в определенную оболочку.
reduce содержит в себе сумму исходных данных, умноженных на 2 и отфильтрованных по четности. То есть является родительской для filter, map и исходных данных.

Применяя модификаторы к вьюхам, происходит похожая история.

struct ContentView: View {
var body: some View {
Text("cmd + B, cmd + R")
.background(.red)
.frame(width: 200, height: 200)
}
}

На экране мы увидим красный background только для текста. Вьюха размером 200х200 останется прозрачной. Так происходит, потому что изначально мы обернули текст во вьюху с красным фоном, а потом эту вьюху(с текстом и фоном) обернули во вьюху размером 200х200.
То есть вьюха размером 200х200 является родительской для вьюхи с красным фоном и текстом.

Конец первой части 🙂

околоiOSный канал: cmd+B, cmd+R

18 Jan, 16:22


История одного поста...

В последнем видео по SwiftUI впервые задействовали onAppear, а, следовательно, неплохо было бы разобрать жизненный цикл вьюх.

Ну, думаю, сейчас быстренько напишу про onAppear, onDisappear, task и вот это вот все...
Начал писать. Ничего не клеится...
Писать о том, что onAppear при появлении, а onDisappear при закрытии - неинтересно (хотя тоже нужно). Копаешь чуть глубже, там вообще пи_дец (2 статьи в подтверждение выше).

Начал про Appearing. Потом понимаешь, что Appearing связан с рендерингом, рендеринг с Attribute Graph, Attribute Graph с View Tree.

Послушал Chris Eidhof. Окончательно понял, что в один пост это все не залезет, а некоторые вопросы лучше вообще в видеоформате сделать.

В общем и целом, было принято решение никуда не торопиться и адекватно разобраться с вопросом хотя бы чуть глубже поверхностного понимания.

Поэтому первый пост будет связан с базовым пониманием построения View Tree и Render Tree (он же Attribute Graph).

Читать пост | Оформить подписку

П.С. Ответ на опрос выше напишу завтра, по итогу сегодня ничего не успел...

околоiOSный канал: cmd+B, cmd+R

18 Jan, 11:59


Жил до конца, умер как герой

В последнем видео о SwiftUI мы первый раз наткнулись на onAppear.

Для лучшего понимания собрался написать пост о жизненном цикле вью в SwiftUI, а заодно зацепить view и render tree.

Поиски информации привели меня на 2 интересные статьи, с которыми, я думаю, вам стоит ознакомится.

П.С. По факту это одна статья из 2 частей

Статья №1 | Статья №2

околоiOSный канал: cmd+B, cmd+R

14 Jan, 13:45


В содержание добавил раздел SwiftUI, внутри него подразделы.

Записал первое видео для 4-ого приложения из курса Sean Allen.
П.С. 4-ое приложение Шон собирает за 6 часов, поэтому будет несколько частей.

Смотреть видео | Оформить подписку

околоiOSный канал: cmd+B, cmd+R

14 Jan, 09:43


Ахаха, я звезда 🥸

околоiOSный канал: cmd+B, cmd+R

14 Jan, 08:18


SwiftUI: Custom TabBar

Залил видос на YouTube.
В 19:00 станет доступен 🍎

околоiOSный канал: cmd+B, cmd+R

13 Jan, 19:21


SwiftUI: Custom TabBar + animation

Немного задержался с записью видео, поэтому на ютуб выложу завтра вечерком.

На бусти уже доступно!
Сказка на ночь :)

П.С. Еще 1,5 часа для "старых" подписчиков скидка 30%

Смотреть видео | Оформить подписку

околоiOSный канал: cmd+B, cmd+R

13 Jan, 09:04


Старый Новый Год

Вечно путаюсь когда отмечают Старый Новый Год...
Вроде бы в ночь с 13 на 14, а может и нет...

Для старых новых подписчиков, скидка 30% на подписку "ЭТО БАЗА!"
Действует 13 января

С праздничком (или с наступающим) 🍾

околоiOSный канал: cmd+B, cmd+R

13 Jan, 08:12


Первый кастомный UI на СУЙ

Изучение SwiftUI это, конечно, здорово, но хочется же попробовать что-то поинтереснее :)

На ютубе наткнулся на видео с созданием кастомного таббара, решил попробовать.

К сожалению, в оригинальном видео (ссылку скину в видео, лень включать впн) нет объяснения, только музыка.

Надо исправить это недоразумение :)
А пока я записываю видео стоит прочитать про:
- ViewBuilder
- Namespace

Давайте соберем 10 лайков и закину видео на ютуб 🍿

околоiOSный канал: cmd+B, cmd+R

11 Jan, 14:55


Кругом эта фраза...
Дурею с этой прикормки :)

околоiOSный канал: cmd+B, cmd+R

11 Jan, 11:35


При создании второго приложения мы научились интегрировать компоненты UIKit в SwiftUI.

При создании третьего приложения мы получали данные от компонента UIKit и отображали их в SwiftUI.

В видео я старался максимально подробно объяснить всю цепочку передачи данных, но, чтобы лучше закрепить знания, написал 2 поста на эту тему. Надеюсь они станут шпаргалками, которые помогут вам в будущем.

Также рассмотрел ситуацию, которой не было в видео, а именно: Обновление компонента UIKit из SwiftUI.

Читать:
- SwiftUI: UIViewControllerRepresentable
- SwiftUI: Context.coordinator

П.С. Создание 4-ого приложения у Шона занимает 6 с половиной часов. Стоит хорошенько подготовится :)

околоiOSный канал: cmd+B, cmd+R

10 Jan, 16:00


К чему это я?

Добавил пост о Binding.
Для лучшего понимания, неплохо было бы вспомнить о projectedValue.

В конце поста добавил информацию для размышления о том, как работает Binding под капотом.

Читать пост | Оформить подписку

околоiOSный канал: cmd+B, cmd+R

09 Jan, 16:08


UIKit -> SwiftUI #3

Записал видео с созданием 3-го приложения на SwiftUI.

Если вы пережили 2020 год, то, скорее всего, вы представляете как сделать сканер QR-кодов на UIKit :)

Основная идея - использовать в SwiftUI проекте элемент из UIKit, который передает данные.

П.С. Пост про Binding напишу в ближайшее время.
Там и так все понятно, но все равно стоит добавить

Смотреть видео | Угостить 🍺

околоiOSный канал: cmd+B, cmd+R

09 Jan, 05:36


Доброе утро 🍎

В дополнение к ObservableObject написал пост о StateObject

околоiOSный канал: cmd+B, cmd+R

08 Jan, 19:37


Простите, но это и правда смешно...
П.С. В какой-то момент я начинаю жалеть HRов...

околоiOSный канал: cmd+B, cmd+R

08 Jan, 12:07


Немного о протоколе ObservableObject

View имеет следующую реализацию:

struct ContentView: View {
@StateObject var updater = DelayedUpdater()

var body: some View {
Text("Value is: \(updater.value)")
}
}


У нее есть viewModel

final class DelayedUpdater: ObservableObject {
@Published var value = 0

init() {
(1...5).forEach {
DispatchQueue.main.asyncAfter(deadline: .now() + Double($0)) {
self.value += 1
print(self.value)
}
}
}
}

околоiOSный канал: cmd+B, cmd+R

08 Jan, 09:30


Минутка новостей :)

1. Записал второе видео по перекату из UIKit в SwiftUI.
2. Написал пост про протокол ObservableObject.
3. Добавил в навигацию раздел UIKit -> SwiftUI.
Для приложений добавил видео превьюхи.

На бусти наконец-то появились адекватные тайм-коды. Добавил их для первого и второго видео.

Смотреть видео | Оформить подписку

околоiOSный канал: cmd+B, cmd+R

06 Jan, 16:56


Не прыгай по верхушкам...

Индивидуальные занятия + опыт поведения курсов подсказывает, что необходимо не заучивать информацию, а понимать что происходит.

Помните свои первые вопросы/мысли:
- когда использовать класс, а когда структуру?
- когда какое свойство использовать?
- когда нужен протокол, а когда нет?
- когда писать weak, когда unowned, а когда вообще ничего не надо?
- и т.д.

В первом видео по SwiftUI было все понятно, кроме свойств, отмеченных как State.

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

По мере изучения обертки будут добавляться. В голове начнет завариваться каша. Причем иногда все будет работать даже с Binding вместо State.

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

Написал пост про State. Напомнил что такое Property Wrapper, и что же за магия скрывается под капотом.

На 100% не уверен, но, скорее всего, на собеседовании это спросят. А раз это все равно учить, то лучше это делать плавно, по мере изучения.

В общем и целом:
Читать "SwiftUI: @State" | Поддержать подпиской

околоiOSный канал: cmd+B, cmd+R

06 Jan, 16:13


Зафиналим

околоiOSный канал: cmd+B, cmd+R

06 Jan, 16:00


По привычке class изначально создал :)
П.С. кто не ставит лайки, тот будет весь год на созвонах

околоiOSный канал: cmd+B, cmd+R

06 Jan, 15:17


Давненько не было опросов.
Пишу пост про propertyWrapper, поэтому вот :)

околоiOSный канал: cmd+B, cmd+R

05 Jan, 13:32


SwiftUI, видео-1

Смотреть на YouTube | boosty

околоiOSный канал: cmd+B, cmd+R

05 Jan, 13:29


Изучение SwiftUI, видео-1

Ранее я писал, что начал изучать SwiftUI по курсу Sean Allen.
Посмотрел первые 2 часа. Понравилось качество материала, но подача...

Для тех кто перекатывается из UIKit слишком подробно.
Для тех кто идет с нуля - нет объяснения, что такое Stack и как он работает.

Но явно не мне его критиковать 🙂

Кстати, посмотрев всего 2 часа, я окончательно убедился, что перекатываться из UIKit гораааааааздо легче, чем сразу начить со SwiftUI (стеки в пример).

Решил собрать гайд по перекату из UIKit в SwiftUI. Начну с курса Sean'а, дополню статьями (например, что такое State) и далее буду пробовать более сложные вещи.
___

Записал 1-ое видео по SwiftUI. По факту, это перевод первых 2-х часов курса Sean'а минус ненужная/повторяющаяся (на мой взгляд) информация. Видео получилось на 30 минут.

Для кого это видео?
1. Для тех, кто хочет сэкономить время.
2. Для тех, кому тяжело воспринимать видео на английском языке.
- Яндекс-браузер, к сожалению, не поможет.
Видимо, перевод выключен для слишком долгих видео.
- Включая русские субтитры, вы потратите еще больше времени на изучение.

околоiOSный канал: cmd+B, cmd+R

05 Jan, 09:56


Доказано нейросетями...

Хотел сделать обложку для видео. Типа переезд с UIKit на SwiftUI.

Результат говорит сам за себя :)

околоiOSный канал: cmd+B, cmd+R

04 Jan, 12:47


Прошел почти год...многое поменялось 🙂

околоiOSный канал: cmd+B, cmd+R

04 Jan, 10:55


SwiftUI: Начало

Изучение SwiftUI начал с Sean Allen. Буду рассказывать о мыслях, которые возникают в процессе обучения.

Информация может быть не на 100% верная, поэтому ее лучше проверять :)

Мысль, которая мне показалось важной, связана с деревом вьюх.

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

На изображении показано примерное дерево приложения.
В ZStack расположены 2 вьюхи:
- Вьюха с градиентом
- VStack (все, кроме градиента)

Смена времени суток происходит при изменении свойства. SwiftUI необходимо определить вьюхи, которые необходимо перерисовать. Насколько я понимаю, происходит обход дерева.

Из всего вышесказанного можно сделать вывод, что проектировать небходимо таким образом, чтобы изменяемые вьюхи были выше в иерархии.

В данном примере, HStack с погодой на каждый день расположен внутри VStack. Вьюхи HStack будут также изменяться при изменении, следовательно, HStack неплохо бы поднять на уровень с Gradient и VStack.

околоiOSный канал: cmd+B, cmd+R

02 Jan, 13:34


Новогодняя суета не дает записать видео...

Не забываем про "Бери и делай!"

Не получается записать видео, надо делать стрим 👨🏻‍💻

Старт в 18:00

околоiOSный канал: cmd+B, cmd+R

02 Jan, 08:02


Домашнее задание

Пока кто-то запивает водку водкой, кто-то решает задачки.
Новогодние праздники они такие 🙂

Решил записать видео с разбором задания из домашней работы курса «Foundation».
Домашняя работа на тему «Функции высшего порядка».
Пройденные темы можно посмотреть здесь.

Напишу задание сюда, возможно, кому-то будет интересно выполнить его самостоятельно и сравнить результаты.
___

Задача:
Необходимо написать программу для учета финансов.

Функционал
1. добавление трат с указанием конкретного дня
2. просмотр трат за определенный день (с возможностью выбора валюты)
3. просмотр трат за весь период пользования приложением (с возможностью выбора валюты)

Пункт 1:
Когда пользователь установил приложение, это считается днем №1.
Если пользователь использует приложение на протяжении 2-х месяцев, то идет 60(или 61) день и т.д.
Данные хранятся в рублях в двумерном массиве.

Выбор валют:
На выбор доступно 3 варианта: рубль, доллар, евро.
Курс можно задать самостоятельно.

Пункт 2:
Метод принимает на вход номер дня и валюту.
Метод выводит собщение в консоль:
Ваши траты за _(номер дня из входных параметров) день: _(обозначение валюты)_(сумма), _(такой же вывод информации, если есть еще траты). Итого: _(обозначение валюты)_(сумма)

Пример:
За 4ый день было 2 траты на 300р и 400р. Сообщение в консоле выглядит следующим образом (если валюта указана рубль):
Ваши траты за 4 день: ₽300, ₽400. Итого: ₽700

Пункт 3:
Метод принимает на вход валюту.
Метод выводит сообщение в консоль.
Дни, в которые не было трат, никак не отображаются в консоли.

Пример:
1 день траты - 100р
4 день траты - 300р, потом еще 400
7 день траты - 500р

Сообщение в консоли:
Ваши траты за 1 день: ₽100. Итого: ₽100
Ваши траты за 4 день: ₽300, ₽400. Итого: ₽700
Ваши траты за 7 день: ₽500. Итого: ₽500
Траты за все время:
₽1300

В данной работе методы должны содержать ТОЛЬКО функции высшего порядка.
Циклы for-in, while, repeat использовать НЕЛЬЗЯ!

П.С. Решение можете скинуть мне в личку 🙂

околоiOSный канал: cmd+B, cmd+R

01 Jan, 12:04


Первое сообщение 2025

Первое сообщение в году должно мотивировать и заставлять что-то делать, учитывая предыдущий опыт. Это не пожелание на новый год, а призыв к действию!

Пусть 2025 станет…
Нет, давайте не так! Это не год должен стать, это мы с вами должны стать лучшей версией себя.

Секрет успеха довольно прост:
Бери и делай!

Давайте в этом году сделаем все то, о чем мы давно мечтали задумывались.
Лучше сделать и пожалеть один раз, чем всю жизнь жалеть о том, что не сделал.

П.С. Я начну со SwiftUI 💇‍♂️