티스토리 뷰

반응형

[ 이슈 ] 

Deployment Target이 iOS 13인 앱에서 value change를 감지하기 위해

onChange(of:perform:) 를 사용하려고 했으나 onChange는 iOS 14부터 지원되는 것이였습니다,,, 

 

애플의 Picker 를 예제로 대응책을 살펴보겠습니다! 

 

 

방법 1 )  onReceive(_:perform:) 는 iOS 13부터 가능하므로 이것을 써준다. 

 

 

onReceive에 Publisher 타입을 넘겨줘야하므로 Just 로 감싸줘야하는데,

이를 위해 import Combine 해줘야합니다. 

 

import SwiftUI
import Combine

enum Flavor: String, CaseIterable, Identifiable {
    case chocolate
    case vanilla
    case strawberry

    var id: String { self.rawValue }
}

struct SomeView: View {
    @State private var selectedFlavor = Flavor.chocolate
    
    var body: some View {
        Picker("Flavor", selection: $selectedFlavor) {
            Text("Chocolate").tag(Flavor.chocolate)
            Text("Vanilla").tag(Flavor.vanilla)
            Text("Strawberry").tag(Flavor.strawberry)
        }
        .pickerStyle(SegmentedPickerStyle())
        .onReceive(Just(selectedFlavor), perform: { value in
            print(value)
        })
    }
}

 

 

방법 2)  extension 을 만든다. 

 

import Combine 해주기도 싫고 iOS14+ 에서는 onReceive말고 onChange 쓰고 싶은데,  iOS 버전 분기해주기도 싫고... 할 때

extension을 만들어서 사용할 수 있습니다. 

이 블로그에서 보고 따라해줬습니다. 

 

import SwiftUI
import Combine

extension View {
    /// A backwards compatible wrapper for iOS 14 `onChange`
    @ViewBuilder func valueChanged<T: Equatable>(value: T, onChange: @escaping (T) -> Void) -> some View {
        if #available(iOS 14.0, *) {
            self.onChange(of: value, perform: onChange)
        } else {
            self.onReceive(Just(value)) { (value) in
                onChange(value)
            }
        }
    }
}

 

import SwiftUI

struct SomeView: View {
    @State private var selectedFlavor = Flavor.chocolate
    
    var body: some View {
        Picker("Flavor", selection: $selectedFlavor) {
            Text("Chocolate").tag(Flavor.chocolate)
            Text("Vanilla").tag(Flavor.vanilla)
            Text("Strawberry").tag(Flavor.strawberry)
        }
        .pickerStyle(SegmentedPickerStyle())
        .valueChanged(value: selectedFlavor, onChange: { value in
            print(value)
        })
    }
}

 

 

[ Reference ] 

 

https://betterprogramming.pub/implementing-swiftui-onchange-support-for-ios13-577f9c086c9

 

Implementing SwiftUI’s OnChange Modifier for iOS 13

Let’s add backward-compatibility support for the latest SwiftUI feature

betterprogramming.pub

 

 

반응형
댓글