Из-за ограничений SwiftUI мне обычно приходится возвращаться к UIKit и использовать компоненты UIKit. Это все хорошо, но я обнаружил, что мне обычно нужно продолжать создавать отдельные структуры, чтобы содержать нужные мне функции.
Например. Допустим, у меня есть форма с 4 полями, например, имя, фамилия, адрес электронной почты и пароль. Мне обычно нужно создавать отдельные компоненты UIViewRepresentable UIKit для каждого.
В настоящее время я работаю над проектом, в котором у меня есть 2 простых ползунка, которые обновляют 2 разных метки при их перемещении. Повторное использование одного и того же компонента UIViewRepresentable UISlider в SwiftUI рассматривает оба ползунка как 1, поскольку они оба ссылаются на одно и то же свойство модели представления, поэтому мне нужно создавать отдельные компоненты, а не использовать их повторно.
Я подумал, что я мог бы также просто увидеть если есть более эффективный способ сделать это, поскольку я уже давно копирую код, и обычно в коде нет большой разницы, кроме таких вещей, как тип отображаемой клавиатуры, colors et c .
Ниже приведен пример того, как я подключаюсь к UIKit из SwiftUI. Я создаю экран, который позволит выбирать коэффициенты ставок и ставки с помощью ползунков.
Я отслеживаю изменение значения ползунка и сохраняю значение в переменной @Published из моей модели представления.
self.bViewModel.odds
Я получаю доступ к этой модели представления через переменную среды в представлении, где ползунок используется и используется для обновления текстовой метки.
VStack {
HStack(spacing: 0) {
Text("\(self.bViewModel.odds)")
.font(Font.system(size: 15, weight: .semibold, design: .default))
.foregroundColor(Color("CustomPurple"))
.frame(minHeight: 0)
.padding(.top, 3)
.padding(.bottom, 3)
Spacer()
}
SliderView()
.frame(minHeight: 25, maxHeight: 25)
}
.padding(.bottom, 30)
Структура SliderView выглядит следующим образом:
struct SliderView: UIViewRepresentable {
final class Coordinator: NSObject {
@EnvironmentObject var bViewModel: BViewModel
init(bViewModel: EnvironmentObject<BViewModel>)
{
self._bViewModel = bViewModel
}
// Create a valueChanged(_:) action
@objc func valueChanged(_ sender: UISlider) {
self.bViewModel.odds = Double(sender.value)
}
}
func makeCoordinator() -> SliderView.Coordinator {
Coordinator(bViewModel: self._bViewModel)
}
@EnvironmentObject var bViewModel: BViewModel
func makeUIView(context: Context) -> UISlider {
let slider = UISlider(frame: .zero)
slider.minimumValue = 0.00
slider.maximumValue = 100.00
slider.addTarget(
context.coordinator,
action: #selector(Coordinator.valueChanged(_:)),
for: .valueChanged
)
return slider
}
func updateUIView(_ uiView: UISlider, context: Context) {
}
}
Теперь мне нужен ползунок для выбора ставки, но я не могу использовать один и тот же слайдер сверху, не написав кучу кода, чтобы он воспринимал его как другой слайдер. Просто проще продублировать код и изменить строку, в которой я получаю доступ к переменной odds моей модели представления, чтобы она вместо этого получала доступ к переменной stakes, например,
@objc func valueChanged(_ sender: UISlider) {
self.bViewModel.stake = Double(sender.value)
}
Вот так я работаю месяцами, но это всегда было неправильно. Тем не менее, я не могу придумать другой способ приблизиться к этому.
Есть предложения? Как вы обычно справляетесь с такой ситуацией?
Заранее спасибо.