ios - Swift: What is the best way to present a Main and Alternative (login/onboarding) Flow? -


i've got app requires person sign in or create account first time app launched. (although not recommended, quite specific use case.)

furthermore, if signed in, when app updated i'd show them screen telling them new features (as notes, photos , music in ios11).

should logic encapsulated in viewcontrollers or in appdelegate?

is there single mechanism can use 1 or more of these scenarios not rely on multiple implementations?

firstly, dealing multiple flows, storyboards can used effectively. default application uses main.storyboard primary flow. onboarding/alternative flow can contained in secondary storyboard, eg. onboarding.storyboard

this has number of advantages:

  • in team of developers, work on each user flow can separated
  • clearer source control (git)
  • separation of concerns

when app launches, can determine flow should presented. logic can contained in appdelegate:

func application(_ application: uiapplication, didfinishlaunchingwithoptions launchoptions: [uiapplicationlaunchoptionskey: any]?) -> bool {     let isfirstrun = true // logic determine goes here     if isfirstrun {         showonboarding()     }     return true } 

in order show onboarding flow, it's worth considering how you'd handle experience of dismissing once person using has completed journey, , semantically correct trying create.

approaches:

the 2 main approaches are:

  1. swap root view controller of app's main window
  2. present onboarding flow modal journey, overlapping main flow.

the implementation of should contained in extension appdelegate.

option 1: swap root view controller (good)


there benefits switching root view controller, although transition options limited supported uiviewanimationoptions, depending on how wish transition between flows might mean have implement custom transition - can cumbersome.

you can show onboarding flow setting uiapplication.shared.keywindow.rootviewcontroller

dismissal handled utilizing uiview.transition(with:) , passing transition style uiviewanimationoptions, in case cross dissolve. (flips , curls supported).

you have set frame of main view before transition it, you're instantiating first time.

// mark: - onboarding  extension appdelegate {      func showonboarding() {         if let window = uiapplication.shared.keywindow, let onboardingviewcontroller = uistoryboard(name: "onboarding", bundle: nil).instantiateinitialviewcontroller() as? onboardingviewcontroller {             onboardingviewcontroller.delegate = self             window.rootviewcontroller = onboardingviewcontroller         }     }      func hideonboarding() {         if let window = uiapplication.shared.keywindow, let mainviewcontroller = uistoryboard(name: "main", bundle: nil).instantiateinitialviewcontroller() {             mainviewcontroller.view.frame = window.bounds             uiview.transition(with: window, duration: 0.5, options: .transitioncrossdissolve, animations: {                 window.rootviewcontroller = mainviewcontroller             }, completion: nil)         }     } } 

option 2: present alternative flow modally (better)


in straightforward implementation, onboarding flow can presented in modal context, since semantically user on single journey.

apple human interface guidelines – modality:

consider creating modal context when it’s critical someone’s attention, when task must completed or abandoned continue using app, or save important data.

presenting modally allows simple option of dismissal @ end of journey, little of cruft of swapping controllers.

custom transitions supported in standard way, since uses viewcontroller.present() api:

// mark: - onboarding  extension appdelegate {      func showonboarding() {         if let window = window, let onboardingviewcontroller = uistoryboard(name: "onboarding", bundle: nil).instantiateinitialviewcontroller() as? onboardingviewcontroller {             onboardingviewcontroller.delegate = self             window.makekeyandvisible()             window.rootviewcontroller?.present(onboardingviewcontroller, animated: false, completion: nil)         }     }      func hideonboarding() {         if let window = uiapplication.shared.keywindow {             window.rootviewcontroller?.dismiss(animated: true, completion: nil)         }     } } 

Comments

Popular posts from this blog

python - Selenium remoteWebDriver (& SauceLabs) Firefox moseMoveTo action exception -

html - How to custom Bootstrap grid height? -

transpose - Maple isnt executing function but prints function term -