Swift インジケーター実装 UIActivityIndicatorView利用しない方法

インジケーターには定番のライブラリがある

github.com

こんなイメージ

https://cloud.githubusercontent.com/assets/1275218/10124182/09f4c406-654f-11e5-9cab-0f2e6f470887.gif

podファイルに記載

  pod 'AppAuth'
  pod 'SwiftDate'
  pod 'Firebase/Crashlytics'
  pod 'TPKeyboardAvoiding'
  
//ここ
  pod 'PKHUD'
  

その後

pod install

利用時 import

import CoreLocation
import SwiftDate

//here
import PKHUD

class DiaryCreateController: BaseViewController, UITabBarControllerDelegate, UINavigationControllerDelegate {

doneボタンで画像upload時間のかかる処理のところに追加する

    @IBAction func doneButtonTapped(_ sender:Any) {

//インジケーター表示
        HUD.show(.progress)
        if isMember(of: DiaryCreateController.self) {
            checkPointsAndDatesThenUploadPhoto()
            return
        }
        
        uploadPhoto() { imgRef in self.saveDiary(photoRef: imgRef) }
    }

GroupDispatureにnotifyしたときにインジケーターを消す

    private func checkPointsAndDatesThenUploadPhoto() {
        var checkPoint = false
        var checkDate = false
        let dpg = DispatchGroup()
        
        dpg.enter()
        checkPoints { (point, err) in
            defer { dpg.leave() }
            if let err = err { print(err) }
            guard let point = point else { return }
            User.loggedIn?.points += point
            User.loggedIn?.save()
            checkPoint = true
        }
        
        // Firebase search
        dpg.enter()
        checkDates {
            defer { dpg.leave() }
            checkDate = $0
        }
        
        dpg.notify(queue: .main) {

//ここ
            guard checkPoint, checkDate else { HUD.hide(); return }
            self.uploadPhoto() { imgRef in self.saveDiary(photoRef: imgRef) }
        }
    }

エラーのときには、インジケーターを消す

    func saveDiary(photoRef: String?) {
        guard  let title_1 = title_1.text else { return }
        guard  let title_2 = title_2.text else { return }
        guard  let title_3 = title_3.text else { return }
        guard let content = calendarText.text else { return }
        
        let new_diary: DocumentReference
        if let id = diary?.documentId {
            new_diary = userREF.collection(DIARY_REF).document(id)
        }
        else { new_diary = userREF.collection(DIARY_REF).document() }
        
        var data = [
            TITLE_1 : title_1,
            TITLE_2 : title_2,
            TITLE_3 : title_3,
            CONTENT: content,
            CREATED_AT: FieldValue.serverTimestamp(),
            UPDATED_AT: FieldValue.serverTimestamp()
        ] as [String : Any]
        
        data[PHOTO] = photoRef
        data[DATE] = Timestamp(date: pickerDate)
        print("uploaded photo: \(photoRef ?? "none")")
        new_diary.setData(data) { error in

//here
            defer { HUD.hide() }
            if let err = error {
                debugPrint(err)
                return
            }else{
                
                self.navigationController?.popToRootViewController(animated: true)
            }
        }
    }

checkData時時間のかかる処理、このときにインジケーターが見えないなら、表示する

   func checkDates(callback: @escaping ((Bool)->Void)) {
        if !HUD.isVisible { HUD.show(.progress) }
        
        FireStoreHelper.getUserRef()?.collection(DIARY_REF).whereField(DATE, isGreaterThanOrEqualTo: pickerDate.date.dateAtStartOf(.day)).limit(to: 1).getDocuments { (snap, error) in
            
            if let err = error?.localizedDescription {
                debugPrint(err)
                callback(false)
                return
            }

            if (snap?.documents.first?.data()[DATE] as? Timestamp)?.dateValue().compare(toDate: self.pickerDate.date, granularity: .day) == .orderedSame {

                let alert = UIAlertController(title: "This date already once", message: nil, preferredStyle: .alert)
                let cancelAction = UIAlertAction(title: "Back without Save", style: .cancel) { (_) in
                    self.navigationController?.popToRootViewController(animated: true)
                }
                let dismissAction = UIAlertAction(title: "Dismiss", style: .default, handler: nil)
                alert.addAction(dismissAction)
                alert.addAction(cancelAction)

                self.present(alert, animated: true, completion: nil)
                callback(false)
                return
            }
            
            callback(true)
        }
    }