根据表视图中的项目数使动态UI按钮显示和消失

时间:2017-05-15 18:10:45

标签: swift uibutton rx-swift

我正在尝试使动态UI按钮显示并根据加载到表视图中的项目数量消失,从后端URL获取。如果有12个或更多项加载到表视图中,我想按钮出现,如果小于12,则不显示。有关处理此问题的最佳方法的任何想法吗?

import UIKit
import RxSwift
import RxCocoa

public class AllProvidersPickerViewController: InputableTableViewController, ViewModelHolder {

    @IBOutlet private(set) weak var searchBar: UISearchBar!
    @IBOutlet weak var dontSeeProviderButton: UIButton!

    var viewModel: AllProvidersPickerViewModel! = nil
    private let bag = DisposeBag()

    override public func viewDidLoad() {
        super.viewDidLoad()
        setupRx()
    }

    private func setupRx() {
      viewModel.shownProviders
        .bind(to: tableView.rx.items(cellIdentifier: "ProviderCell")) { _, mvpd, cell in
            cell.textLabel?.text = mvpd.displayName
        }
        .addDisposableTo(bag)

      tableView
        .rx
        .modelSelected(MVPD.self)
        .bind(to: viewModel.selectedProvider)
        .addDisposableTo(bag)

      searchBar
        .rx.text
        .orEmpty
        .bind(to: viewModel.searchQuery)
        .addDisposableTo(bag)

      dontSeeProviderButton
        .rx.tap
        .bind(to: viewModel.tappedDontSeeProvider)
        .addDisposableTo(bag)
    }
}

private extension MVPD {

    var displayName: String {
        return self.names.first ?? ""
    }
}

2 个答案:

答案 0 :(得分:1)

XFreire的答案很好,或者你可以这样做:

viewModel.shownProviders
    .map { $0.count < 12 }
    .bind(to: dontSeeProviderButton.rx.isHidden)
    .disposed(by: bag)

确保shownProviders可以处理订阅,而无需重新发送任何网络请求或其他任何内容。您可能需要shareReplayLatestWhileConnected()

我被要求解释这段代码......我会通过分解来实现这一点......

let shownProviders = viewModel.shownProviders

此时,我知道shownProviders是一个数组。我不太了解数组所包含的类型,因为该信息不在问题中,但我不需要知道

let shownProviders = viewModel.shownProviders
let shouldHideButton = shownProviders.map { $0.count < 12 }

在上面一行中,我知道$0是一个数组,我知道如果数组中的项目少于12个,该按钮应该隐藏。 $0.count < 12返回Bool。 map会将shownProviders Observable转换为块返回的内容,因此我知道shouldHideButtonObservable<Bool>

let shownProviders = viewModel.shownProviders
let shouldHideButton = shownProviders.map { $0.count < 12 }
let disposable = shouldHideButton.bind(to: dontSeeProviderButton.rx.isHidden)

上面的代码行将shouldHideButton的结果绑定到按钮的isHidden属性。它返回一次性用品。

let shownProviders = viewModel.shownProviders
let shouldHideButton = shownProviders.map { $0.count < 12 }
let disposable = shouldHideButton.bind(to: dontSeeProviderButton.rx.isHidden)
disposable.disposed(by: bag)

最后一行确保在视图控制器超出范围时将破坏绑定。

答案 1 :(得分:0)

最简单的方法:

viewModel.shownProviders
    .subscribe(onNext: { [weak self] items in 
        if items.count < 12 {
            self?.viewAllProvidersButton.isHidden = true
        }
        else {
            self?.viewAllProvidersButton.isHidden = false
        }
    })
    .addDisposableTo(bag)

其他方法可能是创建buttonVisibilityObserver类型的属性AnyObserver并将其绑定到viewModel.shownProviders。这样的事情(未经测试):

var buttonVisibilityObserver: AnyObserver<[ItemsType]> {

    return UIBindingObserver(UIElement: viewAllProvidersButton) { button, items in
        button.isHidden = items.count < 12 ? true : false

    }.asObserver()
}

然后在setupRx()

viewModel.shownProviders
    .bind(to: buttonVisibilityObserver)
    .addDisposableTo(bag)