gpt4 book ai didi

swift - 如何重用 UIViewRepresentable UIKit 组件?

转载 作者:行者123 更新时间:2023-12-04 15:33:23 29 4
gpt4 key购买 nike

由于 SwiftUI 的限制,我通常需要跳回 UIKit 并利用 UIKit 组件。这一切都很好,但我发现我通常需要继续创建单独的结构来保存我需要的功能。

例如。假设我有一个包含 4 个字段的表单,例如名字、姓氏、电子邮件和密码。我通常需要为每个组件创建单独的 UIViewRepresentable UIKit 组件。

我目前正在做一个项目,我有 2 个简单的 slider ,当它们移动时会更新 2 个不同的标签。在 SwiftUI 中重用相同的 UIViewRepresentable UISlider 组件会将两个 slider 视为 1,因为它们都引用相同的 View 模型属性,因此我需要创建单独的组件而不是重用它们。

我想我不妨看看是否有更有效的方法来执行此操作,因为我已经复制代码很长一段时间了,而且代码通常没有太大区别要显示的键盘类型、颜色等。

下面是我如何从 SwiftUI 使用 UIKit 的示例。我正在创建一个屏幕,允许使用 slider 选择投注赔率和赌注。

我跟踪 slider 的值何时更改,并将该值存储在我的 View 模型中的@Published var 中。

self.bViewModel.odds

我通过使用 slider 的 View 中的环境变量访问此 View 模型,并使用它来更新文本标签。

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) {

}
}

现在,我需要一个 slider 来选择赌注,但我无法在不编写一堆代码以使其将其视为不同 slider 的情况下重复使用上面的相同 slider 。复制代码并更改我访问 View 模型的 odds 变量的行更容易,以便它访问 stakes 变量,例如

    @objc func valueChanged(_ sender: UISlider) {

self.bViewModel.stake = Double(sender.value)
}

这就是我工作几个月的方式,但总感觉不对。但是,我似乎想不出另一种方法来解决这个问题。

有什么建议吗?你通常如何处理这种情况?

提前致谢。

最佳答案

新的答案,现在有 EnvironmentObject

import SwiftUI
import Combine

class ViewModel : ObservableObject {

@Published var sliderValue1 : Double = 3.14
@Published var sliderValue2 : Double = 42.0
@Published var sliderValue3 : Double = 3.14
@Published var sliderValue4 : Double = 42.0
}

struct SliderView: UIViewRepresentable {

@Binding var value : Double

class Coordinator: NSObject {
var sliderView: SliderView

init(_ sliderView: SliderView) {
self.sliderView = sliderView
}

@objc func valueChanged(_ slider: UISlider) {
sliderView.value = Double(slider.value)
}
}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

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) {

}
}

struct ContentView : View {

@EnvironmentObject var viewModel : ViewModel

var body: some View {
VStack {
Text("\(self.viewModel.sliderValue1)")
Slider(value: Binding<Double>(get:
{ return self.viewModel.sliderValue1 },
set: {
print($0)
self.viewModel.sliderValue1 = $0
}))

Text("\(self.viewModel.sliderValue2)")
Slider(value: Binding<Double>(get:
{ return self.viewModel.sliderValue2 },
set: {
print($0)
self.viewModel.sliderValue2 = $0
}))


Text("\(viewModel.sliderValue3)")
SliderView(value: Binding<Double>(get:
{ return self.viewModel.sliderValue3 },
set: {
print($0)
self.viewModel.sliderValue3 = $0
}))
Text("\(viewModel.sliderValue4)")
SliderView(value: Binding<Double>(get:
{ return self.viewModel.sliderValue4 },
set: {
print($0)
self.viewModel.sliderValue4 = $0
}))
}
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {

var value1 : Double = 0.4
var value2 : Double = 0.4
var value3 : Double = 0.4
var value4 : Double = 0.4

return ContentView().environmentObject(ViewModel())
}
}

好吧,因为你很有礼貌而且真的很快回答我试过了,希望现在我得到了你需要的东西;)

我确实让“旧 slider ”在其中,但现在下面的两个 slider 来 self 的 UIViewRepresentable。

新答案:

struct SliderView: UIViewRepresentable {

@Binding var value : Double

class Coordinator: NSObject {
var sliderView: SliderView

init(_ sliderView: SliderView) {
self.sliderView = sliderView
}

@objc func valueChanged(_ slider: UISlider) {
sliderView.value = Double(slider.value)
}
}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

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) {

}
}

struct ContentView : View {

@State var sliderValue1 : Double
@State var sliderValue2 : Double

@State var sliderValue3 : Double
@State var sliderValue4 : Double

var body: some View {
VStack {
Text("\(sliderValue1)")
Slider(value: Binding<Double>(get:
{ return self.sliderValue1 },
set: {
print($0)
self.sliderValue1 = $0
}))

Text("\(sliderValue2)")
Slider(value: Binding<Double>(get:
{ return self.sliderValue2 },
set: {
print($0)
self.sliderValue2 = $0
}))


Text("\(sliderValue3)")
SliderView(value: Binding<Double>(get:
{ return self.sliderValue3 },
set: {
print($0)
self.sliderValue3 = $0
}))
Text("\(sliderValue4)")
SliderView(value: Binding<Double>(get:
{ return self.sliderValue4 },
set: {
print($0)
self.sliderValue4 = $0
}))
}
}
}

旧答案:

好的,我想出了没有 UIViewRepresentable 的方法。

请参阅此示例。

您所要做的就是使用您的 sliderVariables(sliderValue1 或您喜欢的任何名称)扩展您的 viewModel 和

struct ContentView : View {

@State var sliderValue1 : Double
@State var sliderValue2 : Double

var body: some View {
VStack {
Text("\(sliderValue1)")
Slider(value: Binding<Double>(get:
{ return self.sliderValue1 },
set: {
print($0)
self.sliderValue1 = $0
}))

Text("\(sliderValue2)")
Slider(value: Binding<Double>(get:
{ return self.sliderValue2 },
set: {
print($0)
self.sliderValue2 = $0
}))
}
}
}

关于swift - 如何重用 UIViewRepresentable UIKit 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60611495/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com