2016-04-18 2 views
4

Мне нужно показать индикатор выполнения при вызове API и скрыть его после завершения вызова API. Ниже приведен код, который я написал для заполнения таблицы. Где я должен делать вызовы, чтобы показывать и скрывать прогресс для вызываемого API? Есть ли способ сделать это RxSwift?Rxswift - как показать индикатор выполнения

items = fetchAllAnswers() 
items.bindTo(self.myTableView.rx_itemsWithCellIdentifier("cellIdentifier", cellType: UITableViewCell.self)){ (row, element, cell) in 
    cell.textLabel?.text = element 
} 
.addDisposableTo(disposeBag) 

func fetchAllAnswers() -> Observable<[String]>{ 
    let api = Observable.create { (obsever: AnyObserver<[String]>) -> Disposable in 
     //progress.show() 
     let items = Api.getUsers() 

     obsever.onNext(items) 
     obsever.onCompleted() 
     //progress.hide 
     return AnonymousDisposable{ 
      print("api dispose called") 
     } 
    } 
    return api 
} 

ответ

6

Вы можете использовать ActivityIndicator из RxSwift repo. Я использую MBProgressHUD в своем проекте. Сначала вам нужно создать расширение для этой библиотеки:

extension MBProgressHUD { 

    /** 
    Bindable sink for MBProgressHUD show/hide methods. 
    */ 
    public var rx_mbprogresshud_animating: AnyObserver<Bool> { 
     return AnyObserver { event in 
      MainScheduler.ensureExecutingOnScheduler() 

      switch (event) { 
      case .Next(let value): 
       if value { 
        let loadingNotification = MBProgressHUD.showHUDAddedTo(UIApplication.sharedApplication().keyWindow?.subviews.last, animated: true) 
        loadingNotification.mode = self.mode 
        loadingNotification.labelText = self.labelText 
        loadingNotification.dimBackground = self.dimBackground 
       } else { 
        MBProgressHUD.hideHUDForView(UIApplication.sharedApplication().keyWindow?.subviews.last, animated: true) 
       } 
      case .Error(let error): 
       let error = "Binding error to UI: \(error)" 
       #if DEBUG 
        rxFatalError(error) 
       #else 
        print(error) 
       #endif 
      case .Completed: 
       break 
      } 
     } 
    } 
} 

Далее необходимо создать объект ActivityIndicator в классе ViewController:

let progress = MBProgressHUD() 
progress.mode = MBProgressHUDMode.Indeterminate 
progress.labelText = "Loading..." 
progress.dimBackground = true 

let indicator = ActivityIndicator() 
indicator.asObservable() 
    .bindTo(progress.rx_mbprogresshud_animating) 
    .addDisposableTo(bag) 

Следующая просто использовать trackActivity() функция в ваши последовательности:

apiMethod 
.trackActivity(indicator) 
.subscribeNext { stringArray in 
    items.value = stringArray 
} 
.addDisposableTo(bag) 
+0

путем привязки к «ProgressHUD» в «viewDidLoad», он начинает показывать его. Перед вызовом функции trackActivity –

+0

«MBProgressHUD» начинает показываться только при вызове функции trackActivity. Я использую его во всех своих проектах. Если «MBProgressHUD» показывается перед вызовом «trackActivity», возможно, вы делаете что-то неправильно. Вы можете проверить учебник RxSwift https://github.com/svyatoslav-reshetnikov/ReactiveApp и посмотреть, как я его реализовал. – Svyatoslav

1

Вы должны сделать эту работу в вашем ViewController, что-то вроде этого:

var disposeBag = DisposeBag() 

...

items = fetchAllAnswers() 
     .subscribeOn(backgroundWorkScheduler) 
     .observeOn(mainScheduler) 
     .subscribe(
       onNext: { data in 
        print("onNext") 
        //show/update progress 
       }, 
       onCompleted: { 
        print("onCompleted") 
        //hide progress 
       }, 
       onDisposed: { 
        print("onDisposed") 
       } 
     ).addDisposableTo(disposeBag) 
0

Свифта 4

extension MBProgressHUD { 
var rx_mbprogresshud_animating: AnyObserver<Bool> { 

    return AnyObserver { event in 

     MainScheduler.ensureExecutingOnScheduler() 

     switch (event) { 
     case .next(let value): 
      if value { 
       let loadingNotification = MBProgressHUD.showAdded(to: (UIApplication.shared.keyWindow?.subviews.last)!, animated: true) 
       loadingNotification.mode = self.mode 
       loadingNotification.label.text = self.label.text 
      } else { 
       MBProgressHUD.hide(for: (UIApplication.shared.keyWindow?.subviews.last)!, animated: true) 
      } 
     case .error(let error): 
      let error = "Binding error to UI: \(error)" 
      print(error) 
     case .completed: 
      break 
     } 
     } 
    } 
    } 
+1

Возможно, вы добавите разъяснение коду? – evolutionxbox

Смежные вопросы