Slide 1

Slide 1 text

RootViewControllerͰ ը໘ભҠΛ·ͱΊͨ࿩ ROPPONGI.swift ୈ2ճ 2018೥4݄2೔ ࠤ౻߶࢜ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 1

Slide 2

Slide 2 text

Who am I ࠤ౻߶࢜ (@hatakenokakashi) MAMORIOגࣜձࣾͰiOSΤϯδχΞ͠ ͍ͯ·͢ɻ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 2

Slide 3

Slide 3 text

UIViewControllerͷભҠํ๏͓͞Β ͍ present(nextVC, animated: true, completion: nil) navigationController?.pushViewController(nextVC, animated: true) ·ͨ͸segueΛ࢖͏ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 3

Slide 4

Slide 4 text

ը໘ભҠͷͳ΍ΈͲ͜Ζ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 4

Slide 5

Slide 5 text

ը໘ભҠ͸ભҠݩͷը໘͔Β࣮ߦ ↓ ։ൃ͕͢͢ΜͰɺը໘͕૿͑ͯ͘Δͱͭ Β͍ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 5

Slide 6

Slide 6 text

ͭΒ͍͜ͱ • ΞϓϦશମͷը໘ભҠ͕Θ͔Γʹ͘͘ͳΔ(ͦΕͧΕͷ ViewControllerΫϥεͷ࣮૷Λ1ͭͮͭΈͳ͍ͱ͍͚ͳ͍) • ༷ʑͳ৚݅Ͱىಈը໘Λมߋ͍ͨ͠ͱ͖ίʔυ͕൥ࡶʹͳΔ • ະϩάΠϯ/ϩάΠϯͰىಈ࣌ͷViewControllerΛ෼͚͍ͨͱ͖ • ϓογϡ௨஌ɺ3DTouchγϣʔτΧοτͳͲͰಛఆͷը໘Λ දࣔ͢Δͱ͍͏࣮૷͕ਏ͍ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 6

Slide 7

Slide 7 text

RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 7

Slide 8

Slide 8 text

RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 8

Slide 9

Slide 9 text

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { let naviCon = application.windows[0] .rootViewController as? UINavigationController RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 9

Slide 10

Slide 10 text

//࠷ޙʹද͍ࣔͯͨ͠ը໘Λ൑அͯ͠ભҠΛ͢Δ //ද͍ࣔͯ͠ΔViewController͕ϝΠϯϏϡʔͳΒઃఆը໘ʹભҠɻ //͢Ͱʹઃఆը໘Λද͍ࣔͯ͠ΔͳΒɺίϯςφϏϡʔΛදࣔͤ͞Δɻ if let visibleMainViewCon = naviCon?.visibleViewController as? CallMainViewController { visibleMainViewCon.performSegue(withIdentifier: "gotoSettingFromPush", sender: true) } else if let visibleSettingViewCon = naviCon?.visibleViewController as? SettingViewController { // visibleSettingViewCon. visibleSettingViewCon.isFromPush.value = true visibleSettingViewCon.hiddenReplyViews(ishidden: !visibleSettingViewCon.isFromPush.value) } else if !(naviCon?.viewControllers.last is SettingViewController) { let popVC = naviCon?.popViewController(animated: true) print("ϙοϓͨ͠VC͸ \(type(of: popVC))") if let visibleSettingViewCon = naviCon?.visibleViewController as? SettingViewController { visibleSettingViewCon.isFromPush.value = true visibleSettingViewCon.hiddenReplyViews(ishidden: !visibleSettingViewCon.isFromPush.value) } } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 10

Slide 11

Slide 11 text

! RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 11

Slide 12

Slide 12 text

RootViewControllerͰ ղܾ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 12

Slide 13

Slide 13 text

RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 13

Slide 14

Slide 14 text

ํ਑ • RootViewControllerͱ͍͏ΫϥεΛ࡞Δ • windowsͷrootViewControllerʹಥͬࠐΉ • ը໘ભҠ͸RootViewControllerʹࢠViewControllerΛ૊Έࠐ Ή͜ͱͰ࣮ߦ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 14

Slide 15

Slide 15 text

αϯϓϧΞϓϦ঺հ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 15

Slide 16

Slide 16 text

RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 16

Slide 17

Slide 17 text

RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 17

Slide 18

Slide 18 text

ϓϩδΣΫτͷMain InterfaceΛۭʹ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 18

Slide 19

Slide 19 text

AppDelegate func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { setup() return true } private func setup() { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = router.rootViewController window?.makeKeyAndVisible() } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 19

Slide 20

Slide 20 text

private let _router = Router() extension AppDelegate { static var shared: AppDelegate { guard let delegate = UIApplication.shared.delegate as? AppDelegate else { fatalError("not set app delegate") } return delegate } var router: Router { return _router } } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 20

Slide 21

Slide 21 text

final class Router { enum Locate { case login case main case camera case setting } let rootViewController = RootViewController() func route(to locate: Locate, from viewController: UIViewController) { switch locate { case .login: rootViewController.showLoginScreen() break case .main: rootViewController.showMain() case .camera: rootViewController.showCameraScreen() break case .setting: rootViewController.showSettingScreen() break } } } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 21

Slide 22

Slide 22 text

class RootViewController: UIViewController { private var current: UIViewController init() { //ىಈ࣌͸ඞͣεϓϥογϡը໘Λදࣔ current = SplashViewController() super.init(nibName: nil, bundle: nil) } override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.blue addChildViewController(current) current.view.frame = view.bounds view.addSubview(current.view) current.didMove(toParentViewController: self) } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 22

Slide 23

Slide 23 text

// RootViewController // MARK: ΞϓϦͰߦ͏۩ମతͳભҠ func showLoginScreen() { let new = LoginViewController.instantiate() addChildViewController(new) new.view.frame = view.bounds view.addSubview(new.view) new.didMove(toParentViewController: self) replaceCurrent(for: new) } func showMain() { switch current { case let tab as TabViewController: tab.selectMain() default: let tab = TabViewController.instantiate() animateFadeTransition(to: tab) } } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 23

Slide 24

Slide 24 text

࢖༻ྫ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 24

Slide 25

Slide 25 text

Splashը໘ͷग़͠෼͚ func onViewDidload() { if UserDefaults.standard.bool(forKey: "IS_LOGIN") { //ϝΠϯը໘Λදࣔ AppDelegate.shared.router.route(to: .main, from: self) } else { UserDefaults.standard.set(true, forKey: "IS_LOGIN") //ϩάΠϯը໘Λදࣔ AppDelegate.shared.router.route(to: .login, from: self) } } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 25

Slide 26

Slide 26 text

3D TouchγϣʔτΧοτͰಛఆը໘ ભҠ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 26

Slide 27

Slide 27 text

struct DeepLinkShortcut { enum ItemType: String { case main case camera case setting } static func register() -> [UIApplicationShortcutItem] { let mainShortcutItem = UIApplicationShortcutItem(type: ItemType.main.rawValue, localizedTitle: "ϝΠϯը໘") let cameraShortcutItem = UIApplicationShortcutItem(type: ItemType.camera.rawValue, localizedTitle: "Χϝϥը໘") let settingShortcutItem = UIApplicationShortcutItem(type: ItemType.setting.rawValue, localizedTitle: "ઃఆը໘") return [mainShortcutItem, cameraShortcutItem, settingShortcutItem] } static func handleShortcut(_ shortcut: UIApplicationShortcutItem) -> ItemType? { return ItemType(rawValue: shortcut.type) } } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 27

Slide 28

Slide 28 text

// AppDelegate private func setup() { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = router.rootViewController window?.makeKeyAndVisible() UIApplication.shared.shortcutItems = DeepLinkShortcut.register() } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 28

Slide 29

Slide 29 text

// AppDelegate // MARK: Shortcuts func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { if let shortCut = DeepLinkShortcut.handleShortcut(shortcutItem) { let route = AppDelegate.shared.router switch shortCut { case .main: route.route(to: .main, from: route.rootViewController) case .camera: route.route(to: .camera, from: route.rootViewController) case .setting: route.route(to: .setting, from: route.rootViewController) } } completionHandler(true) } RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 29

Slide 30

Slide 30 text

Demo RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 30

Slide 31

Slide 31 text

ιʔείʔυ https://github.com/SatoTakeshiX/RootViewController RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 31

Slide 32

Slide 32 text

ੵۃతʹϝϯόʔืूதʂ https://www.wantedly.com/companies/mamorio • iOSΤϯδχΞ • AndroidΤϯδχΞ • UI/UXσβΠφʔ RootViewControllerͰը໘ભҠΛ·ͱΊͨ࿩ 32