Titus
Titus

Reputation: 349

How to create a dynamic stepped Progress Bar in swift?

I have an existing app, wherein upon opening the app the default steps in progress bar are UserType, Credentials, Email, Password, Confirm Password, Agreement and Done, The app requires some changes when it comes to its Stepped Progress Bar, by the way I used FlexibleSteppedProgressBar pod for the progress bar. My problem is, the app has three(3) UserTypes. The two user types(User1, User2) should have 8 steps as follows UserType, Credentials, Email, Password, Confirm Password, Agreement and Done, while the one user type (User3) has 7 steps only (without the Agreement Step). How can I modify the progress bar when the user taps the User3 the steps in the Progress Bar should be 7 steps only and when the user taps User1 User2 user types, the default progress bar with 8 steps should be retain. I am bit confuse since I am new in swift programming and I am modifying an existing app that needs some revisions which I am not the original one who created the app. I tried some modifications, I added additional two structs which contains 7 Steps and 8 Steps upon tapping the User3 the struct for 7 steps will be called and turned into 7 steps but the MasterViewController layout still not modified the original 8 steps just overlapped in the modified 7 steps, meaning it looks like two progress bar overlapped appeared in my app.

Page.swift

struct Page {

static let titles: [String] = ["User Type",
                              "Credential",
                              "Birthdate",
                              "Email",
                              "Password",
                              "Confirm",
                              "Agreement",
                              "Done"]
}

Page2.swift

struct Page2 {

static let titles: [String] = ["User Type",
                              "Credential",
                              "Birthdate",
                              "Email",
                              "Password",
                              "Confirm",
                             // "Agreement",
                              "Done"]
 }

MasterViewController.swift

override func viewDidLoad() {
    super.viewDidLoad()

    configureNotificationObserver()
    setupView()
    configureAnimationView()
}

// MARK: VIEW CONTROLLER INITIALIZATIONS

   private lazy var roleViewController: RoleViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "RoleViewController") as! RoleViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()

   private lazy var firstCredentialViewController: FirstCredentialViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "FirstCredentialViewController") as! FirstCredentialViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()

   private lazy var birthdateViewController: BirthdateViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "BirthdateViewController") as! BirthdateViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()

    private lazy var emailViewController: EmailViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "EmailViewController") as! EmailViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()

    private lazy var passwordViewController: PasswordViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "PasswordViewController") as! PasswordViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()

    private lazy var confirmPasswordViewController: ConfirmPasswordViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "ConfirmPasswordViewController") as! ConfirmPasswordViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()

    private lazy var termsAndConditionsViewController: TermsAndConditionsViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "TermsAndConditionsViewController") as! TermsAndConditionsViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()


private lazy var doneViewController: DoneViewController = {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let viewController = storyboard.instantiateViewController(withIdentifier: "DoneViewController") as! DoneViewController
    self.add(asChildViewController: viewController)

    return viewController
  }()

  // MARK: FUNCTIONS

  private func add(asChildViewController viewController: UIViewController) {
    addChildViewController(viewController)

    containerView.addSubview(viewController.view)

    viewController.view.frame = view.bounds
    viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    viewController.didMove(toParentViewController: self)
  }

  private func remove(asChildViewController viewController: UIViewController) {
    viewController.willMove(toParentViewController: nil)
    viewController.view.removeFromSuperview()
    viewController.removeFromParentViewController()
  }

  private func configureAnimationView() {
    gearsAnimationView.frame = CGRect(x: 350, y: 160, width: 300, height: 200)
    gearsAnimationView.contentMode = .scaleAspectFit
    gearsAnimationView.loopAnimation = true

    loadingContainerView.addSubview(gearsAnimationView)
  }


   private func setupSteppedProgressBar() {
    progressBar.numberOfPoints = Page.titles.count
    progressBar.lineHeight = 8
    progressBar.radius = 15
    progressBar.progressRadius = 20
    progressBar.progressLineHeight = 3
    progressBar.delegate = self

    progressBar.stepTextColor = UIColor.lightGray
    progressBar.stepTextFont = UIFont.init(name: "HelveticaNeue", size: 15.0)
    progressBar.selectedBackgoundColor = UIColor(red: 82/255, green: 177/255, blue: 108/255, alpha: 1.0)

    // CURRENT SELECTED
    progressBar.currentSelectedCenterColor = UIColor(red: 244/255, green: 69/255, blue: 93/255, alpha: 1.0)
    progressBar.selectedOuterCircleStrokeColor = UIColor(red: 244/255, green: 69/255, blue: 93/255, alpha: 1.0)
    progressBar.currentSelectedTextColor = UIColor(red: 56/255, green: 56/255, blue: 56/255, alpha: 1.0)
}

   func updateView() {

    let currentIndex = progressBar.currentIndex

    switch currentIndex {
       case 0:
        remove(asChildViewController: firstCredentialViewController)
        add(asChildViewController: roleViewController)
        case 1:
        remove(asChildViewController: roleViewController)
        add(asChildViewController: firstCredentialViewController)
        case 2:
        remove(asChildViewController: firstCredentialViewController)
        add(asChildViewController: birthdateViewController)
        case 3:
        remove(asChildViewController: birthdateViewController)
        add(asChildViewController: emailViewController)
        case 4:
        remove(asChildViewController: emailViewController)
        add(asChildViewController: passwordViewController)
        case 5:
        remove(asChildViewController: passwordViewController)
        add(asChildViewController: confirmPasswordViewController)
        case 6:
        remove(asChildViewController: confirmPasswordViewController)
       // add(asChildViewController: termsAndConditionsViewController)
        case 7:
     //   remove(asChildViewController: termsAndConditionsViewController)
        add(asChildViewController: doneViewController)
        default: break
      }
   }

    private func setupView() {
    setupSteppedProgressBar()
    updateView()
   }

private func configureNotificationObserver() {
    NotificationCenter.default.addObserver(self, selector: #selector(self.nextStep), name: NSNotification.Name(rawValue: "nextStep"), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.previousStep), name: NSNotification.Name(rawValue: "previousStep"), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.showLoading), name: NSNotification.Name(rawValue: "showLoading"), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.hideLoading), name: NSNotification.Name(rawValue: "hideLoading"), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.successfulUserCreated), name: NSNotification.Name(rawValue: "UserCreated"), object: nil)
   }

//sample typing 

@objc func nextStep() {

    let currentIndex = progressBar.currentIndex
    let totalNumberOfPoints = progressBar.numberOfPoints

    switch currentIndex {
    case 0:
        firstCredentialViewController.userRole = roleViewController.userRole

    case 1:
        birthdateViewController.userRole = firstCredentialViewController.userRole
        birthdateViewController.firstCredential = firstCredentialViewController.firstCredential
    case 4:
        confirmPasswordViewController.userRole = birthdateViewController.userRole
        confirmPasswordViewController.firstCredential = birthdateViewController.firstCredential
        confirmPasswordViewController.emailString = emailViewController.emailString
        confirmPasswordViewController.passwordString = passwordViewController.passwordString
   // case 5:
     //   termsAndConditionsViewController.userRole = confirmPasswordViewController.userRole
    //    termsAndConditionsViewController.firstCredential = confirmPasswordViewController.firstCredential
     //   termsAndConditionsViewController.emailString = confirmPasswordViewController.emailString
      //  termsAndConditionsViewController.confirmPasswordString = confirmPasswordViewController.passwordString
    default: break
    }

    if currentIndex < (totalNumberOfPoints - 1) {
        progressBar.currentIndex = currentIndex + 1
        updateView()
    }
}

@objc func previousStep() {

    let currentIndex = progressBar.currentIndex

    progressBar.currentIndex = currentIndex - 1
    updateView()



@objc func showLoading() {
    isLoading(on: true)
}

@objc func hideLoading() {
    isLoading(on: false)
}

@objc func successfulUserCreated() {
    clearAllData()
    progressBar.currentIndex = 0
    updateView()
}

private func clearAllData() {

    // RoleViewController
   roleViewController.userRole = nil

    // FirstCredentialViewController
    firstCredentialViewController.userRole = nil
    firstCredentialViewController.firstCredential = nil
    firstCredentialViewController.titleLabel.text = ""
    firstCredentialViewController.credentialTextField.text = ""

    // BirthdateViewController
    birthdateViewController.userRole = nil
    birthdateViewController.firstCredential = nil
    birthdateViewController.birthdate = nil

    // EmailViewController
    emailViewController.emailString = nil
    emailViewController.emailAddressTextField.text = ""

    // PasswordViewController
    passwordViewController.passwordString = nil
    passwordViewController.passwordTextField.text = ""

    // ConfirmPasswordViewController
    confirmPasswordViewController.userRole = nil
    confirmPasswordViewController.firstCredential = nil
    confirmPasswordViewController.passwordString = nil
    confirmPasswordViewController.confirmPasswordTextField.text = ""

    //TermsAndConditionsViewController
    termsAndConditionsViewController.proceedButton.isEnabled = false
    termsAndConditionsViewController.checkButton.isSelected = false
  }

 }

extension MasterViewController {

func progressBar(_ progressBar: FlexibleSteppedProgressBar, canSelectItemAtIndex index: Int) -> Bool {
    return false
}

func progressBar(_ progressBar: FlexibleSteppedProgressBar, textAtIndex index: Int, position: FlexibleSteppedProgressBarTextLocation) -> String {

    if position == FlexibleSteppedProgressBarTextLocation.bottom {

        return Page.titles[index]
    }

    return ""
  }
 }

Upvotes: 1

Views: 1228

Answers (0)

Related Questions