SwiftUI dev
1.17K subscribers
87 photos
37 videos
1 file
74 links
Mobile development, SwiftUI, Compose, feel free to reach me: @lexkraev
Download Telegram
Modern swift API design.pdf
2.3 MB
Modern Swift API Design
https://developer.apple.com/videos/play/wwdc2019/415/
Отличная презентация про современной подход к дизайну API приложения, поднимаются такие вопросы, как какие типы - value или reference - использовать и где, когда лучше вводить протоколы, а когда дженерики (общий посыл: не надо чрезмерно злоупотреблять протоколами (принцип less code is better), а чаще использовать generic типы), рассказывают про PropertyWrappers (ключевая аннотация при объявление @propertyWrapper) и их роль в SwiftUI.

#watchthis
SwiftUI dev
Modern swift API design.pdf
This media is not supported in your browser
VIEW IN TELEGRAM
Главное:
1. Binding, State - это property wrappers
2. Компилятор раскрывает property wrapper в stored property/storage (сохраняемое состояние) и computed property (вычисляемое состояние), в случае с Binding storage ссылается на storage State в геттере.
3. Именно из storage SwiftUI и отрисовывает View после изменения Binding или State.
4. У Binding дополнительно введен аттрибут dynamicMemberLookup (который вызывает subscript при доступе к свойству:
$slide.title -> $slide[dynamicMemder: \Slide.title])
5. Привязка Binding к State работает через префикс $

#readthis
SwiftUI dev pinned a photo
SwiftUI dev pinned «Meet async/await in Swift https://developer.apple.com/videos/play/wwdc2021/10132/ ❗️Главное: 1. Async/await существенно сокращает код, позволяет не думать о всех случаях в замыканиях 2. ⚙️ Принцип работы строится на следующем: если синхронная процедура возвращает…»
SwiftUI dev pinned «Discover concurrency in SwiftUI https://developer.apple.com/videos/play/wwdc2021/10019/ Рассмотрим следующий код: class Photos: ObservableObject { @Published var items: [Photos] = [] func updateItems() { let fetched = fetchPhotos() items = fetched…»
SwiftUI dev pinned «Protect mutable state with Swift actors https://developer.apple.com/videos/play/wwdc2021/10133/ 1️⃣ Обзор на сессию выложу в виде последовательных постов (номер по порядку смотрите в начале поста), так как инфы оч много, а тема достаточно интересная и нетрививальная.…»
SwiftUI dev pinned a file
This media is not supported in your browser
VIEW IN TELEGRAM
Наглядный пример, почему Apple депрекэйтнула модификатор .animation с одним параметром (типом анимации): из-за некорректной отрисовки самой анимации, SUI не понимает, на какое именно событие анимировать. 👇🏻

#readthis
SwiftUI dev
Наглядный пример, почему Apple депрекэйтнула модификатор .animation с одним параметром (типом анимации): из-за некорректной отрисовки самой анимации, SUI не понимает, на какое именно событие анимировать. 👇🏻 #readthis
Рассмотрим, код:

Предположим, хотим сделать zoom-zoom анимацию при тапе на кнопку. Для этого сделаем модификатор:

public struct ScaleButtonStyle: ButtonStyle {
public init() {}

public func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.scaleEffect(configuration.isPressed ? 0.95 : 1)
.animation(.linear(duration: 0.2))
.brightness(configuration.isPressed ? -0.05 : 0)
}
}

public extension ButtonStyle where Self == ScaleButtonStyle {
static var scale: ScaleButtonStyle {
ScaleButtonStyle()
}
}


Далее применим этот модификатор для отрисовки элемента в горизонтальном Lazy стэке:

ScrollView(.horizontal, showsIndicators: false) {
LazyHStack {
ForEach(data, id: \.self) { card in
Button {

} label: {
VStack(alignment: .leading
) {
AsyncImage(…)
.resizable()
.frame(width: elementSize.width, height: elementSize.height)
.cornerRadius(8)

Text(…)
.boldFont(…)
.foregroundColor(…)
}
}
.buttonStyle(ScaleButtonStyle())
}
}


В итоге получаем представленный баг: некорректная анимация на onAppear в lazy стеке. Фиксим путем добавления value в .animation, тем самым указывая конкретное значение для отслеживания изменений.

public struct ScaleButtonStyle: ButtonStyle {
public init() {}

public func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.scaleEffect(configuration.isPressed ? 0.95 : 1)
.animation(.linear(duration: 0.2), value: configuration.isPressed)
.brightness(configuration.isPressed ? -0.05 : 0)
}
}


#readthis