@@ -2,7 +2,7 @@ | |||||
/// Пропускаем лишь значения от UI | /// Пропускаем лишь значения от UI | ||||
/// | /// | ||||
/// - Returns: Значение без префиксов "a:"/"u:" | /// - Returns: Значение без префиксов "a:"/"u:" | ||||
func onlyAcceptUIText(_ s: String) -> String? { | |||||
func onlyUIText(_ s: String) -> String? { | |||||
guard s.hasPrefix("u:") else { return nil } | guard s.hasPrefix("u:") else { return nil } | ||||
return String(s.dropFirst(2)) | return String(s.dropFirst(2)) | ||||
} | } |
@@ -0,0 +1,26 @@ | |||||
import Combine | |||||
import SwiftUI | |||||
extension Cord { | |||||
final class TextField: ObservableObject { | |||||
@Published var value = "a:" | |||||
var subscriptions = [AnyCancellable]() | |||||
init( | |||||
_ textApp: String, | |||||
_ textUI: String | |||||
) { | |||||
Bus.send( | |||||
textUI, | |||||
$value.compactMap(onlyUIText).eraseToAnyPublisher(), | |||||
sub: &subscriptions | |||||
) | |||||
Bus.receive( | |||||
[textApp], | |||||
{ [weak self] (_, v: String) in self?.value = "a:\(v)" }, | |||||
sub: &subscriptions | |||||
) | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,2 @@ | |||||
public enum Cord { } |
@@ -1,17 +1,18 @@ | |||||
import SwiftUI | import SwiftUI | ||||
struct V: View { | struct V: View { | ||||
@StateObject var tf = Cord.TextField("text.app", "text.ui") | |||||
@StateObject var vm = VM() | @StateObject var vm = VM() | ||||
var body: some View { | var body: some View { | ||||
VStack { | VStack { | ||||
HStack { | HStack { | ||||
Text("Check text field:") | Text("Check text field:") | ||||
Text("'\(vm.text)'") | |||||
Text("'\(tf.value)'") | |||||
.fontWeight(.bold) | .fontWeight(.bold) | ||||
} | } | ||||
TextField("Binding-3", value: $vm.text, formatter: TextFieldValueOwner()) | |||||
TextField("Binding-3", value: $tf.value, formatter: TextFieldValueOwner()) | |||||
.padding(8) | .padding(8) | ||||
.border(Color.blue, width: 2) | .border(Color.blue, width: 2) | ||||
@@ -2,23 +2,26 @@ import Combine | |||||
import SwiftUI | import SwiftUI | ||||
final class VM: ObservableObject { | final class VM: ObservableObject { | ||||
/* | |||||
@Published var text = "a:" | @Published var text = "a:" | ||||
let format = Bus.Processor( | let format = Bus.Processor( | ||||
MeetupId.K.meetupIdTextUI.rawValue, | MeetupId.K.meetupIdTextUI.rawValue, | ||||
MeetupId.K.meetupIdTextApp.rawValue, | MeetupId.K.meetupIdTextApp.rawValue, | ||||
MeetupId.onlyFormat | MeetupId.onlyFormat | ||||
) | ) | ||||
*/ | |||||
var isJoinAvailable = true | var isJoinAvailable = true | ||||
let join = PassthroughSubject<Void, Never>() | let join = PassthroughSubject<Void, Never>() | ||||
var subscriptions = [AnyCancellable]() | var subscriptions = [AnyCancellable]() | ||||
init() { | init() { | ||||
/* | |||||
Bus.send( | Bus.send( | ||||
MeetupId.K.meetupIdTextUI.rawValue, | MeetupId.K.meetupIdTextUI.rawValue, | ||||
$text | $text | ||||
// Исключаем конфликты от UI и App путём игнорирования спама. | // Исключаем конфликты от UI и App путём игнорирования спама. | ||||
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main) | .debounce(for: .seconds(0.3), scheduler: DispatchQueue.main) | ||||
.compactMap(onlyAcceptUIText) | |||||
.compactMap(onlyUIText) | |||||
.eraseToAnyPublisher(), | .eraseToAnyPublisher(), | ||||
sub: &subscriptions | sub: &subscriptions | ||||
) | ) | ||||
@@ -29,5 +32,6 @@ final class VM: ObservableObject { | |||||
opt: [.async], | opt: [.async], | ||||
sub: &subscriptions | sub: &subscriptions | ||||
) | ) | ||||
*/ | |||||
} | } | ||||
} | } |