如何在移动UISlider时获取值?
我正在使用以下代码:
视图模型:
import Foundation
import RxSwift
final class ViewModel {
private let disposeBag = DisposeBag()
var value: Variable<Float>
init() {
self.value = Variable(Float(0.0))
}
}
的ViewController:
@IBOutlet var slider: UISlider!
private var viewModel: ViewModel!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
viewModel = ViewModel()
slider.rx.value
.subscribe(onNext: { (value) in
self.viewModel.value = Variable(Float(value))
})
.addDisposableTo(disposeBag)
}
但是这段代码不起作用。我的错是什么?
答案 0 :(得分:5)
您正在替换变量而不是在其中插入新值。这保证会失败。
ViewModel.value
应该是let
而不是var
。您不想替换变量,您想要将新值分配到中。当你在它时,使你的ViewModel成为一个结构:
struct ViewModel {
let value = Variable<Float>(0)
}
如果必须,可以是最后一堂课,但value
应该仍然是let
而不是var
。
您的viewDidLoad
应如下所示:
public override func viewDidLoad() {
super.viewDidLoad()
slider.rx.value
.subscribe(onNext: { value in
self.viewModel.value.value = value
})
.disposed(by: disposeBag)
}
或者更好:
public override func viewDidLoad() {
super.viewDidLoad()
slider.rx.value
.bind(to: viewModel.value)
.disposed(by: disposeBag)
}
甚至更好......订阅ViewModel.value的任何东西都应该直接订阅/绑定到slider.rx.value。这样你就可以摆脱中间人。
这样的事情:
public class ViewController: UIViewController {
@IBOutlet weak var slider: UISlider!
@IBOutlet weak var label: UILabel!
private let disposeBag = DisposeBag()
public override func viewDidLoad() {
super.viewDidLoad()
slider.rx.value
.map { "The slider's value is \($0)" }
.bind(to: label.rx.text)
.disposed(by: disposeBag)
}
}
移动滑块时,您会看到标签的文字发生变化。
答案 1 :(得分:4)
未经测试,但我会尝试:
override func viewDidLoad() {
viewModel = ViewModel()
slider.rx.value
.subscribe(onNext: { (value) in
self.viewModel.value.value = Float(value)
})
.addDisposableTo(disposeBag)
}
另外,我会将value
中的viewModel
属性重命名为sliderValue
(或其他,但不是value
)。如果这样做,您的代码看起来会更好:
self.viewModel.sliderValue.value = Float(value)
而不是
self.viewModel.value.value = ...
答案 2 :(得分:2)
如果您使用新的BehaviorRelay
而不是旧的Variable
:
struct MyViewModel {
let value = BehaviorRelay<Float>(value: 0)
}
class ViewController: UIViewController {
@IBOutlet var slider: UISlider!
@IBOutlet var valueLabel: UILabel!
private var viewModel = MyViewModel()
override func viewDidLoad() {
super.viewDidLoad()
slider.rx.value
.bind(to: viewModel.value)
.disposed(by: rx.disposeBag)
// If you want to listen and bind to a label
viewModel.value.asDriver()
.map { "Value: \($0 * 100)%" }
.drive(valueLabel.rx.text)
.disposed(by: rx.disposeBag)
}
}