|
|
|
@ -8,12 +8,14 @@
|
|
|
|
|
import UIKit
|
|
|
|
|
import RxSwift
|
|
|
|
|
import RxCocoa
|
|
|
|
|
import DZNEmptyDataSet
|
|
|
|
|
import SVProgressHUD
|
|
|
|
|
|
|
|
|
|
class ViewController: UIViewController, Navigatable {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var viewModel: ViewModel?
|
|
|
|
|
var navigator: Navigator!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init(viewModel: ViewModel?, navigator: Navigator) {
|
|
|
|
|
self.viewModel = viewModel
|
|
|
|
|
self.navigator = navigator
|
|
|
|
@ -23,13 +25,10 @@ class ViewController: UIViewController, Navigatable {
|
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// let isLoading = BehaviorRelay(value: false)
|
|
|
|
|
// let error = PublishSubject<ApiError>()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let isLoading = BehaviorRelay(value: false)
|
|
|
|
|
let error = PublishSubject<ApiError>()
|
|
|
|
|
|
|
|
|
|
var automaticallyAdjustsLeftBarButtonItem = true
|
|
|
|
|
var canOpenFlex = true
|
|
|
|
|
|
|
|
|
@ -41,31 +40,40 @@ class ViewController: UIViewController, Navigatable {
|
|
|
|
|
|
|
|
|
|
let spaceBarButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lazy var backBarButton: UIBarButtonItem = {
|
|
|
|
|
let button = UIButton.init()
|
|
|
|
|
button.imageEdgeInsets = UIEdgeInsets.init(top: 0, left: -10, bottom: 0, right: 0)
|
|
|
|
|
button.setTitleColor(UIColor(red: 0.25, green: 0.25, blue: 0.25, alpha: 1.00), for: .normal)
|
|
|
|
|
button.setImage(UIImage(named:"nav_back_btn"), for: .normal)
|
|
|
|
|
button.addTarget(self, action: #selector(backAction), for: .touchUpInside)
|
|
|
|
|
|
|
|
|
|
let leftBarBtn = UIBarButtonItem(customView: button)
|
|
|
|
|
|
|
|
|
|
return leftBarBtn
|
|
|
|
|
}()
|
|
|
|
|
let emptyDataSetButtonTap = PublishSubject<Void>()
|
|
|
|
|
var emptyDataSetTitle = ""
|
|
|
|
|
var emptyDataSetDescription = ""
|
|
|
|
|
var emptyDataSetImage = UIImage.init(named: "")
|
|
|
|
|
var emptyDataSetImageTintColor = BehaviorRelay<UIColor?>(value: nil)
|
|
|
|
|
|
|
|
|
|
let languageChanged = BehaviorRelay<Void>(value: ())
|
|
|
|
|
|
|
|
|
|
let orientationEvent = PublishSubject<Void>()
|
|
|
|
|
let motionShakeEvent = PublishSubject<Void>()
|
|
|
|
|
|
|
|
|
|
lazy var backBarButton: BarButtonItem = {
|
|
|
|
|
let view = BarButtonItem()
|
|
|
|
|
view.title = ""
|
|
|
|
|
return view
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
lazy var closeBarButton: BarButtonItem = {
|
|
|
|
|
let view = BarButtonItem(image: UIImage.init(named: ""),
|
|
|
|
|
style: .plain,
|
|
|
|
|
target: self,
|
|
|
|
|
action: nil)
|
|
|
|
|
return view
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
lazy var contentView: View = {
|
|
|
|
|
let view = View()
|
|
|
|
|
// view.hero.id = "CententView"
|
|
|
|
|
self.view.addSubview(view)
|
|
|
|
|
view.snp.makeConstraints { (make) in
|
|
|
|
|
make.edges.equalTo(self.view)
|
|
|
|
|
make.edges.equalTo(self.view.safeAreaLayoutGuide)
|
|
|
|
|
}
|
|
|
|
|
return view
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override public func viewDidLoad() {
|
|
|
|
|
super.viewDidLoad()
|
|
|
|
@ -74,9 +82,18 @@ class ViewController: UIViewController, Navigatable {
|
|
|
|
|
makeUI()
|
|
|
|
|
bindViewModel()
|
|
|
|
|
|
|
|
|
|
// Observe device orientation change
|
|
|
|
|
closeBarButton.rx.tap.asObservable().subscribe(onNext: { [weak self] () in
|
|
|
|
|
self?.navigator.dismiss(sender: self)
|
|
|
|
|
}).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
NotificationCenter.default
|
|
|
|
|
.rx.notification(UIDevice.orientationDidChangeNotification).mapToVoid()
|
|
|
|
|
.bind(to: orientationEvent).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
orientationEvent.subscribe { [weak self] (event) in
|
|
|
|
|
self?.orientationChanged()
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
// Observe application did become active notification
|
|
|
|
|
NotificationCenter.default
|
|
|
|
|
.rx.notification(UIApplication.didBecomeActiveNotification)
|
|
|
|
|
.subscribe { [weak self] (event) in
|
|
|
|
@ -86,7 +103,7 @@ class ViewController: UIViewController, Navigatable {
|
|
|
|
|
NotificationCenter.default
|
|
|
|
|
.rx.notification(UIAccessibility.reduceMotionStatusDidChangeNotification)
|
|
|
|
|
.subscribe(onNext: { (event) in
|
|
|
|
|
// logDebug("Motion Status changed")
|
|
|
|
|
logDebug("Motion Status changed")
|
|
|
|
|
}).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -94,63 +111,91 @@ class ViewController: UIViewController, Navigatable {
|
|
|
|
|
|
|
|
|
|
public override func viewWillAppear(_ animated: Bool) {
|
|
|
|
|
super.viewWillAppear(animated)
|
|
|
|
|
|
|
|
|
|
if automaticallyAdjustsLeftBarButtonItem {
|
|
|
|
|
adjustLeftBarButtonItem()
|
|
|
|
|
}
|
|
|
|
|
updateUI()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override func viewDidAppear(_ animated: Bool) {
|
|
|
|
|
super.viewDidAppear(animated)
|
|
|
|
|
updateUI()
|
|
|
|
|
|
|
|
|
|
logResourcesCount()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deinit {
|
|
|
|
|
|
|
|
|
|
logDebug("\(type(of: self)): Deinited")
|
|
|
|
|
logResourcesCount()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override public func didReceiveMemoryWarning() {
|
|
|
|
|
super.didReceiveMemoryWarning()
|
|
|
|
|
// Dispose of any resources that can be recreated.
|
|
|
|
|
logDebug("\(type(of: self)): Received Memory Warning")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func makeUI() {
|
|
|
|
|
//用于消除左边空隙,要不然按钮顶不到最前面
|
|
|
|
|
// let spacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil,
|
|
|
|
|
// action: nil)
|
|
|
|
|
// spacer.width = -10
|
|
|
|
|
// self.navigationItem.leftBarButtonItems = [spacer, backBarButton]
|
|
|
|
|
|
|
|
|
|
view.backgroundColor = .white
|
|
|
|
|
// navigationItem.leftBarButtonItem = backBarButton
|
|
|
|
|
|
|
|
|
|
navigationItem.backBarButtonItem = backBarButton
|
|
|
|
|
|
|
|
|
|
updateUI()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func bindViewModel() {
|
|
|
|
|
// viewModel?.loading.asObservable().bind(to: isLoading).disposed(by: rx.disposeBag)
|
|
|
|
|
viewModel?.parsedError.asObservable().bind(to: error).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
languageChanged.subscribe(onNext: { [weak self] () in
|
|
|
|
|
self?.emptyDataSetTitle = ""
|
|
|
|
|
}).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
isLoading.subscribe(onNext: { isLoading in
|
|
|
|
|
// UIApplication.shared.isNetworkActivityIndicatorVisible = isLoading
|
|
|
|
|
}).disposed(by: rx.disposeBag)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func updateUI() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func startAnimating() {
|
|
|
|
|
SVProgressHUD.show()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func viewDidLayoutSubviews() {
|
|
|
|
|
super.viewDidLayoutSubviews()
|
|
|
|
|
|
|
|
|
|
func stopAnimating() {
|
|
|
|
|
SVProgressHUD.dismiss()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
|
|
|
|
|
if motion == .motionShake {
|
|
|
|
|
motionShakeEvent.onNext(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func orientationChanged() {
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
|
|
|
|
self.updateUI()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func didBecomeActive() {
|
|
|
|
|
self.updateUI()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MARK: Adjusting Navigation Item
|
|
|
|
|
|
|
|
|
|
func adjustLeftBarButtonItem() {
|
|
|
|
|
if self.navigationController?.viewControllers.count ?? 0 > 1 { // Pushed
|
|
|
|
|
self.navigationItem.leftBarButtonItem = nil
|
|
|
|
|
} else if self.presentingViewController != nil { // presented
|
|
|
|
|
self.navigationItem.leftBarButtonItem = closeBarButton
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@objc func closeAction(sender: AnyObject) {
|
|
|
|
|
self.dismiss(animated: true, completion: nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@objc func backAction() {
|
|
|
|
|
self.navigationController?.popViewController(animated: true)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension ViewController {
|
|
|
|
@ -167,14 +212,47 @@ extension ViewController {
|
|
|
|
|
return view
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension Reactive where Base: ViewController {
|
|
|
|
|
extension ViewController: DZNEmptyDataSetSource {
|
|
|
|
|
|
|
|
|
|
/// Bindable sink for `backgroundColor` property
|
|
|
|
|
var emptyDataSetImageTintColorBinder: Binder<UIColor?> {
|
|
|
|
|
return Binder(self.base) { view, attr in
|
|
|
|
|
// view.emptyDataSetImageTintColor.accept(attr)
|
|
|
|
|
}
|
|
|
|
|
func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
|
|
|
|
|
return NSAttributedString(string: emptyDataSetTitle)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
|
|
|
|
|
return NSAttributedString(string: emptyDataSetDescription)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
|
|
|
|
|
return emptyDataSetImage
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func imageTintColor(forEmptyDataSet scrollView: UIScrollView!) -> UIColor! {
|
|
|
|
|
return emptyDataSetImageTintColor.value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func backgroundColor(forEmptyDataSet scrollView: UIScrollView!) -> UIColor! {
|
|
|
|
|
return .clear
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func verticalOffset(forEmptyDataSet scrollView: UIScrollView!) -> CGFloat {
|
|
|
|
|
return -60
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension ViewController: DZNEmptyDataSetDelegate {
|
|
|
|
|
|
|
|
|
|
func emptyDataSetShouldDisplay(_ scrollView: UIScrollView!) -> Bool {
|
|
|
|
|
return !isLoading.value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView!) -> Bool {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func emptyDataSet(_ scrollView: UIScrollView!, didTap button: UIButton!) {
|
|
|
|
|
emptyDataSetButtonTap.onNext(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|