Open2

iOS Development Scrap

NiaNia

Dynamic Framework -> Static Library のリンク、Dynamic Framework で使ってない宣言は最適化で消えるので、消したくない場合は Dynamic Framework の Other Linker Flags に -all_load を追加する。

NiaNia

Swift Concurrency (async / await) を使った ObservableObject を withAnimation するいい方法がよくわからないので、雑にやる方法。withAnimation で ObservableObject.objectWillChange をラップする AnimationAdaptedObservedObject を作る。

import SwiftUI
import Combine

final class AnimationAdapter<T: ObservableObject>: ObservableObject {

    let target: T
    var animation: Animation?

    private var cancellable: AnyCancellable? = nil

    init(_ target: T, animation: Animation? = nil) {
        self.target = target
        self.animation = animation
        self.cancellable = target
            .objectWillChange
            .subscribe(on: RunLoop.main)
            .sink { [weak self] _ in
                if let animation = self?.animation {
                    withAnimation(animation) {
                        self?.objectWillChange.send()
                    }
                } else {
                    self?.objectWillChange.send()
                }
            }
    }
}

extension ObservableObject {

    typealias AnimationAdapted = AnimationAdapter<Self>

    func adapt(animation: Animation? = nil) -> AnimationAdapted {
        .init(self, animation: animation)
    }
}

async メソッド内部で objectWillChange.send() する場合、外側で withAnimation できない(withAnimation は synchronous なので)