tgoop.com »
United States »
Библиотека мобильного разработчика | Android, iOS, Swift, Retrofit, Moshi, Chuck » Telegram Web
Создание таблицы с различными типами ячеек достаточно стандартная задача. Конечно, можно использовать различное ветвление при помощи if, else или switch, но лучше и практичнее использовать Дженерики.
#свежак #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
❤2🔥1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6
🚀 Курс «ИИ-агенты для DS-специалистов» уже стартовал
Первый вебинар успешно прошёл, участники уже начали разбираться, как использовать ИИ-агентов в реальных проектах.
Но всё самое интересное только начинается!
🔥 Впереди 4 мощных занятия — с практикой, инсайтами и разбором кейсов от экспертов.
💸 Сейчас действует специальная цена → 69.000 ₽ вместо79.000 ₽.
⏳ Осталось всего 4 места.
Не упустите шанс прокачаться в том, что будет определять будущее индустрии.
👉 Забронировать место на курсе
Первый вебинар успешно прошёл, участники уже начали разбираться, как использовать ИИ-агентов в реальных проектах.
Но всё самое интересное только начинается!
🔥 Впереди 4 мощных занятия — с практикой, инсайтами и разбором кейсов от экспертов.
💸 Сейчас действует специальная цена → 69.000 ₽ вместо
⏳ Осталось всего 4 места.
Не упустите шанс прокачаться в том, что будет определять будущее индустрии.
👉 Забронировать место на курсе
В карточках разобрали, как именно меняется обучение будущих айтишников и к чему это может привести.
#MadeInProglib
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Оператор
guard
используется для передачи управления программой за пределы области видимости. Оператор guard
похож на оператор if
, но он запускается только тогда, когда некоторые условия не выполняются.Например, оператор
guard
используется для выхода из функции:func myFun() {
guard false else {
print("This block is run")
return
}
print("This is never run")
}
myFun()
Вывод:
This block is run
#буст #JuniorKit #Swift
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Приготовили для вас дайджест по актуальному из мира iOS, Android и кроссплатформы.
Разобрали, как устроены массивы в Swift под капотом: от базовых операций добавления и удаления до тонкостей работы с value/reference типами. Посмотрели на Copy-on-Write и устройство буфера. Также узнали, почему массивы - это всего лишь обёртки над хранилищем в куче, и чем ArraySlice отличается от обычного массива.
Поговорим ещё об одном встроенном типе Swift - Codable. Думаю, все, кто писал клиент-серверные приложения, сталкивались с этим протоколом: он позволяет преобразовывать наши структуры в бинарные данные и обратно. Однако, полагаю, немногие задумывались, как этот привычный механизм работает под капотом.
Это нарушение основополагающих принципов свободы слова и мысли, которые лежат в основе функционирования демократических обществ по всему миру.
Room не медленный. Медленным его делает неправильное использование.
В этой статье автор поделиться опытом работы с пуш-уведомлениями. Расскажет, с чего начинал, какие проблемы встретил и к чему пришел на текущий момент.
#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
reified — это ключевое слово, которое может быть использовано только в inline-функциях.
reified
позволяет получить информацию о типе generic-параметра во время выполнения программы. В обычном случае, информация о типах стирается и недоступна во время выполнения, но с помощью reified
можно сохранять эту информацию и использовать в других частях приложения.Несколько простых примеров применения:
1. Получить доступ к типу параметра во время выполнения
fun main() {
printType<String>() // String
printType<Int>() // Int
}
private inline fun <reified T> printType() {
println(T::class.simpleName)
}
В этом примере мы определяем функцию
printType()
с типовым параметром T
, который мы указываем с помощью reified
. Внутри функции мы можем получить тип T
во время выполнения, используя T::class
. Затем выводим название типа на экран с помощью simpleName
. Когда мы вызываем функцию printType()
с типом String
или Int
, она выводит соответствующий тип на экран.2.
reified
вместе с is
для проверки типа аргумента во время выполненияfun main() {
println(isOfType<Int>(1)) // true
println(isOfType<Int>("Hello")) // false
}
private inline fun <reified T> isOfType(value: Any): Boolean {
return value is T
}
Здесь мы определяем функцию
isOfType()
, которая принимает значение типа Any
и возвращает true
, если оно является типом T
. Мы используем reified
, чтобы получить доступ к типу T
во время выполнения. Затем мы используем оператор is
для проверки типа значения и возвращаем соответствующее boolean значение.3. Получить список элементов перечисления
enum class Color { RED, GREEN, BLUE }
fun main() {
printEnumValues<Color>() // RED, GREEN, BLUE
}
private inline fun <reified T : Enum<T>> printEnumValues() {
enumValues<T>().forEach { value ->
println(value)
}
}
Определяем функцию
printEnumValues()
, которая выводит список элементов перечисления типа T
. Мы применяем reified
, чтобы получить доступ к типу T
во время выполнения. Затем используем enumValues<T>()
, чтобы получить список всех значений перечисления типа T
. Внутри цикла выводим каждое значение на экран. Когда мы вызываем функцию printEnumValues()
с типом Color
, она выводит "RED", "GREEN" и "BLUE" в консоль.#буст #JuniorKit #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
В SwiftUI alert — это способ показать критически важную информацию или запросить решение у пользователя.
Используй их только для действительно важных случаев: ошибок, подтверждений (особенно разрушительных действий), запросов разрешений.
Самый простой способ — через
isPresented
(булево значение):@State var isPresented = false
VStack {
// UI
}
.alert("Alert Title", isPresented: $isPresented) {
Button("OK") { /* action */ }
Button("Cancel") { }
}
Алёрт появляется, когда
isPresented = true
, и автоматически закрывается после действия пользователя.Можно добавить поясняющий текст:
.alert("Alert Title", isPresented: $isPresented) {
Button("OK") { }
} message: {
Text("Подробнее о проблеме")
}
Это помогает пользователю понять контекст и принять осознанное решение.
📦 Работа с данными
Для подтверждения действий над конкретными объектами есть параметр
presenting
:.alert("Delete Document", isPresented: $isPresented, presenting: document) { document in
Button("Delete", role: .destructive) { delete(document) }
Button("Cancel", role: .cancel) { }
} message: { document in
Text("Удалить '\(document.name)'? Это действие нельзя отменить.")
}
Так SwiftUI сохраняет корректные данные на время отображения диалога.
Если твои ошибки реализуют
LocalizedError
, SwiftUI умеет красиво показывать их в алёртах:.alert(isPresented: $isPresented, error: error) {
Button("Retry") { }
Button("Cancel") { }
} message: { error in
Text(error.recoverySuggestion ?? "Попробуй позже.")
}
Используй краткие заголовки и ясные действия.
Помечай кнопки ролями:
.cancel
, .destructive
.Не перегружай интерфейс — если это не критично, лучше показать баннер или inline-сообщение.
alert
, banner
или sheet
?#АрхитектурныйКод #MiddlePath #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Как превратить свой текущий проект в топливо для следующего, ещё более успешного?
Не обязательно тянуть лямку до полного выгорания. Можно просто продать его тому, у кого есть ресурсы и желание им заниматься.
Наткнулись на канал, где как раз и собираются такие люди — разработчики, инвесторы и покупатели. Там обсуждают сделки, находят партнёров и делают экзиты.
Прицениться, найти покупателя или просто понаблюдать за рынком можно здесь → @approckvc
Не обязательно тянуть лямку до полного выгорания. Можно просто продать его тому, у кого есть ресурсы и желание им заниматься.
Наткнулись на канал, где как раз и собираются такие люди — разработчики, инвесторы и покупатели. Там обсуждают сделки, находят партнёров и делают экзиты.
Прицениться, найти покупателя или просто понаблюдать за рынком можно здесь → @approckvc
🤝1
Утро. Дебаг. Дедлайн. Рука тянется к заветной кружке... Но что в ней должно быть — бодрящий кофе или успокаивающий чай?
Что предпочитаете вы? Голосуйте и пишите своё мнение в комментариях
❤️ — чай
👍 — кофе
🤝 — вода
#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19❤17🤝10
IOS - Разработчик — от 220 000 до 330 000 ₽, офис (Москва)
Android Team Lead — удалёнка
Senior iOS Developer — от 450 000 ₽, удалёнка
Руководитель группы разработки Android (ПВЗ) — от 600 000 ₽, удалёнка
Flutter Developer — от 4 000 до 4 800 €, удалёнка
#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Индикатор пульса — это простой, но эффективный элемент пользовательского интерфейса, который помогает визуализировать состояние подключения или активности. В отличие от индикатора загрузки, он передает идею о сигнале, исходящем из центральной точки, что особенно полезно для отображения состояния GPS или сетевого подключения.
Вот полная составная функция, которая отображает индикатор пульса:
@Composable
закрытый метод PulseIndicator(
@DrawableRes значок: Int,
модификатор: Modifier = Modifier
) {
val periodMs = 3600L
val offsetsMs = longArrayOf(0L, 1200L, 2400L)
val startNs = запомнить { System.nanoTime() }
var frameTimeNs by запомнить { mutableLongStateOf(startNs) }
LaunchedEffect(Единица измерения) {
while (true) {
withFrameNanos { now -> frameTimeNs = now }
}
}
(offsetMs: Long)фазафункция: число с плавающей запятой {
val elapsedMs = (frameTimeNs - startNs) / 1_000_000L + offsetMs
return ((elapsedMs % periodMs).toFloat() / periodMs.toFloat())
}
Box(modifier.size(80.dp), contentAlignment = Alignment.Center) {
(p:
Float )Кольцофункция@Composable = Box(
Модификатор
.matchParentSize()
.graphicsLayer {
scaleX = 1f + 0,8f * p
scaleY = 1f + 0,8f * p
alpha = 1f - p
}
.border(1,5.dp, Color.White.copy(alpha = 0,9f), CircleShape)
)
Кольцо(фаза(смещения[0]))
Кольцо(фаза(смещения[1]))
Кольцо(фаза(смещения[2]))
Box(
Modifier
.size(80.dp)
.background(Color.White, CircleShape),
contentAlignment = Alignment.Center
) {
Image(
painter = painterResource(icon),
contentDescription = null,
modifier = Modifier.size(32.dp)
)
}
}
}
Компонуемый элемент использует
withFrameNanos
внутри LaunchedEffect
. Это позволяет получить доступ к текущей временной метке кадра и обеспечивает плавность анимации, пока компонуемый элемент находится на экране. Когда компонуемый элемент покидает композицию, сопрограмма автоматически отменяется.Функция
phase(offsetMs)
преобразует прошедшее время в значение между 0f
и 1f
. Каждое кольцо смещено (0
, 1200
, 2400
мс), поэтому они расширяются в разные моменты. Это создаёт иллюзию непрерывных волн.Каждое кольцо изображается в виде
Box
с круглой рамкой. Его размер и непрозрачность изменяются с помощью graphicsLayer
:scaleX
и scaleY
постепенно увеличиваются от 1f до 1.8f.alpha
плавно переходит от 1f
к 0f
.Вместе они образуют расширяющийся, затухающий круг.
В центре находится сплошной белый круг с указанным значком (например, с меткой местоположения). Он служит статичной точкой привязки, в то время как анимированные кольца расходятся в стороны.
#PixelPerfect #MiddlePath #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4😁3👾1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8
SQLiteData — это быстрая и лёгкая замена SwiftData от Point-Free, включающая SQL и синхронизацию с CloudKit (и даже шаринг CloudKit), построенная на основе популярной библиотеки GRDB.
Пример:
@FetchAll
var items: [Item]
@Table
struct Item {
let id: UUID
var title = ""
var isInStock = true
var notes = ""
}
Этот пример извлекают элементы из внешнего хранилища данных с использованием типов данных Swift, и автоматически отслеживается SwiftUI, поэтому представления пересчитываются при изменении внешних данных. При этом SQLiteData работает непосредственно с SQLite и может использоваться откуда угодно, включая UIKit, модели @Observable и многое другое.
#буст #iOS
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3