无法从自定义视图传递 RxSwift PublishRelay 值
Can't pass the RxSwift PublishRelay value from custom view
我正在尝试使用 rx 操作扩展我的 KeyboardView 视图,但没有成功。根据断点调试,值被传递给中继,但尽管在视图控制器中有进一步的订阅,但不会调用扩展。可能是什么问题以及如何解决?
final class KeyboardView: UIView {
private let disposeBag = DisposeBag()
fileprivate let buttonTappedRelay = PublishRelay<ActionType>()
private let digitButtons: [KeyboardButton] = {
return stride(from: 0, through: 9, by: 1)
.compactMap { [=10=] }
.map { KeyboardButton(actionType: .digit([=10=])) }
}()
private let eraseButton: KeyboardButton = {
let button = KeyboardButton(actionType: .erase)
return button
}()
public override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupConstraints()
setupActions()
}
private func setupViews() { ... }
private func setupConstraints() { ... }
private func setupActions() {
eraseButton.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
for button in digitButtons {
button.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
}
}
}
extension Reactive where Base: KeyboardView {
internal var buttonTap: ControlEvent<ActionType> {
return ControlEvent<ActionType>(events: base.buttonTappedRelay.asObservable() )
}
}
您的问题可能出在您未显示的代码中。请注意,以下代码编译、运行和工作:
final class KeyboardView: UIView {
private let disposeBag = DisposeBag()
fileprivate let buttonTappedRelay = PublishRelay<ActionType>()
private let digitButtons: [KeyboardButton] = {
return stride(from: 0, through: 9, by: 1)
.compactMap { [=10=] }
.map { KeyboardButton(actionType: .digit([=10=])) }
}()
private let eraseButton: KeyboardButton = {
let button = KeyboardButton(actionType: .erase)
return button
}()
public override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupActions()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
let stack = UIStackView(frame: bounds)
stack.distribution = .equalSpacing
stack.addArrangedSubview(eraseButton)
for each in digitButtons {
stack.addArrangedSubview(each)
}
addSubview(stack)
}
private func setupActions() {
eraseButton.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
for button in digitButtons {
button.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
}
}
}
final class ViewController: UIViewController {
weak var keyboard: KeyboardView?
override func loadView() {
super.loadView()
let keyboard = KeyboardView(frame: view.bounds)
view.addSubview(keyboard)
self.keyboard = keyboard
}
override func viewDidLoad() {
super.viewDidLoad()
keyboard!.rx.buttonTap
.debug("")
.subscribe()
}
}
extension Reactive where Base: KeyboardView {
internal var buttonTap: ControlEvent<ActionType> {
return ControlEvent<ActionType>(events: base.buttonTappedRelay.asObservable() )
}
}
enum ActionType {
case digit(Int)
case erase
}
class KeyboardButton: UIButton {
let actionType: ActionType
init(actionType: ActionType) {
self.actionType = actionType
super.init(frame: CGRect.zero)
backgroundColor = .red
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension Reactive where Base: KeyboardButton {
var buttonTap: Observable<ActionType> {
base.rx.tap.map { base.actionType }
}
}
我正在尝试使用 rx 操作扩展我的 KeyboardView 视图,但没有成功。根据断点调试,值被传递给中继,但尽管在视图控制器中有进一步的订阅,但不会调用扩展。可能是什么问题以及如何解决?
final class KeyboardView: UIView {
private let disposeBag = DisposeBag()
fileprivate let buttonTappedRelay = PublishRelay<ActionType>()
private let digitButtons: [KeyboardButton] = {
return stride(from: 0, through: 9, by: 1)
.compactMap { [=10=] }
.map { KeyboardButton(actionType: .digit([=10=])) }
}()
private let eraseButton: KeyboardButton = {
let button = KeyboardButton(actionType: .erase)
return button
}()
public override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupConstraints()
setupActions()
}
private func setupViews() { ... }
private func setupConstraints() { ... }
private func setupActions() {
eraseButton.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
for button in digitButtons {
button.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
}
}
}
extension Reactive where Base: KeyboardView {
internal var buttonTap: ControlEvent<ActionType> {
return ControlEvent<ActionType>(events: base.buttonTappedRelay.asObservable() )
}
}
您的问题可能出在您未显示的代码中。请注意,以下代码编译、运行和工作:
final class KeyboardView: UIView {
private let disposeBag = DisposeBag()
fileprivate let buttonTappedRelay = PublishRelay<ActionType>()
private let digitButtons: [KeyboardButton] = {
return stride(from: 0, through: 9, by: 1)
.compactMap { [=10=] }
.map { KeyboardButton(actionType: .digit([=10=])) }
}()
private let eraseButton: KeyboardButton = {
let button = KeyboardButton(actionType: .erase)
return button
}()
public override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
setupActions()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
let stack = UIStackView(frame: bounds)
stack.distribution = .equalSpacing
stack.addArrangedSubview(eraseButton)
for each in digitButtons {
stack.addArrangedSubview(each)
}
addSubview(stack)
}
private func setupActions() {
eraseButton.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
for button in digitButtons {
button.rx.buttonTap
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] actionType in
self?.buttonTappedRelay.accept(actionType)
}).disposed(by: self.disposeBag)
}
}
}
final class ViewController: UIViewController {
weak var keyboard: KeyboardView?
override func loadView() {
super.loadView()
let keyboard = KeyboardView(frame: view.bounds)
view.addSubview(keyboard)
self.keyboard = keyboard
}
override func viewDidLoad() {
super.viewDidLoad()
keyboard!.rx.buttonTap
.debug("")
.subscribe()
}
}
extension Reactive where Base: KeyboardView {
internal var buttonTap: ControlEvent<ActionType> {
return ControlEvent<ActionType>(events: base.buttonTappedRelay.asObservable() )
}
}
enum ActionType {
case digit(Int)
case erase
}
class KeyboardButton: UIButton {
let actionType: ActionType
init(actionType: ActionType) {
self.actionType = actionType
super.init(frame: CGRect.zero)
backgroundColor = .red
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension Reactive where Base: KeyboardButton {
var buttonTap: Observable<ActionType> {
base.rx.tap.map { base.actionType }
}
}