Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Introducing PanelKit

787 views

Published on

PanelKit is a UI framework that enables floating and pinned panels on iOS. Learn about the ins and outs of this open source Swift library.

Published in: Technology
  • Be the first to comment

Introducing PanelKit

  1. 1. by Louis D'hauwe
  2. 2. Who? Louis D'hauwe Est. 1995 iOS Developer @ Next Apps College dropout ! #TeamTabs @LouisDhauwe
  3. 3. Demo
  4. 4. A UI framework enabling floating and pinned panels on iOS.
  5. 5. A UI framework enabling floating and pinned panels on iPad.
  6. 6. Why?
  7. 7. Photoshop Fix
  8. 8. Photoshop Fix
  9. 9. Photoshop CC
  10. 10. "real" Photoshop
  11. 11. We can do better!
  12. 12. Performance
  13. 13. Performance CPU iPad Pro 
 (12.9-inch, 2015) MacBook Air 
 (13-inch, 2015) 0 1500 3000 4500 6000 Single-Core Multi-Core 4.157 5.238 2.439 3.083 Source: Geekbench
  14. 14. Hardware is not the issue
  15. 15. Software is
  16. 16. How?
  17. 17. Panels Panel Manager
  18. 18. View Hierarchy
  19. 19. UINavigationController
  20. 20. Root View Controller
  21. 21. Content Wrapper View
  22. 22. Content View
  23. 23. UINavigationController Root View Controller Content Wrapper View Content View
  24. 24. Content View Panel
  25. 25. UINavigationController Root View Controller Content Wrapper View Content View Panel
  26. 26. Technical
  27. 27. v0.8
  28. 28. open class PanelContentViewController: UIViewController { ... open var preferredPanelContentSize: CGSize { fatalError("Preferred panel content size not implemented") } ... } v0.8
  29. 29. open class PanelContentViewController: UIViewController { ... open var preferredPanelContentSize: CGSize { fatalError("Preferred panel content size not implemented") } ... } class FooPanelContentViewController: PanelContentViewController { override var preferredPanelContentSize: CGSize { return CGSize(width: 320, height: 500) } } v0.8
  30. 30. open class PanelContentViewController: UIViewController { ... open var preferredPanelContentSize: CGSize { fatalError("Preferred panel content size not implemented") } ... } class FooPanelContentViewController: PanelContentViewController { override var preferredPanelContentSize: CGSize { return CGSize(width: 320, height: 500) } } Need to implement, otherwise runtime crash! v0.8
  31. 31. Why fatalError? open class PanelContentViewController: UIViewController { ... open var preferredPanelContentSize: CGSize { fatalError("Preferred panel content size not implemented") } ... } v0.8
  32. 32. Why fatalError? Swift has no abstract modifier open class PanelContentViewController: UIViewController { ... open var preferredPanelContentSize: CGSize { fatalError("Preferred panel content size not implemented") } ... } v0.8
  33. 33. Why fatalError? Swift has no abstract modifier open class PanelContentViewController: UIViewController { ... open var preferredPanelContentSize: CGSize { fatalError("Preferred panel content size not implemented") } ... } No default value v0.8
  34. 34. v1.0
  35. 35. Protocol-oriented
  36. 36. Protocol-oriented interface contract
  37. 37. open class PanelContentViewController: UIViewController { ... open var preferredPanelContentSize: CGSize { fatalError("Preferred panel content size not implemented") } ... } Protocol-oriented
  38. 38. public protocol PanelContentDelegate { ... var preferredPanelContentSize: CGSize { get } ... } Protocol-oriented
  39. 39. class FooPanelContentViewController: UIViewController, PanelContentDelegate { } Protocol-oriented
  40. 40. class FooPanelContentViewController: UIViewController, PanelContentDelegate { } Protocol-oriented
  41. 41. class FooPanelContentViewController: UIViewController, PanelContentDelegate { var preferredPanelContentSize: CGSize { return CGSize(width: 320, height: 500) } } Protocol-oriented
  42. 42. class FooPanelContentViewController: UIViewController, PanelContentDelegate { let preferredPanelContentSize = CGSize(width: 320, height: 500) } Protocol-oriented
  43. 43. Protocol-oriented public class PanelViewController: UIViewController, UIAdaptivePresentationControllerDelegate { public init(with contentViewController: UIViewController, contentDelegate: PanelContentDelegate, in panelManager: PanelManager) { ... } ... }
  44. 44. Protocol-oriented public class PanelViewController: UIViewController, UIAdaptivePresentationControllerDelegate { public init(with contentViewController: UIViewController, contentDelegate: PanelContentDelegate, in panelManager: PanelManager) { ... } ... }
  45. 45. public protocol PanelManager { /// The ```UIViewController``` that manages the panels and contains /// ```panelContentWrapperView``` and ```panelContentView```. var managerViewController: UIViewController { get } /// The panels to be managed. var panels: [PanelViewController] { get } /// The view in which the panels may be dragged around. var panelContentWrapperView: UIView { get } /// The content view, which will be moved/resized when panels pin. var panelContentView: UIView { get } ... } Protocol-oriented
  46. 46. public extension PanelManager where Self: UIViewController { var managerViewController: UIViewController { return self } } Protocol-oriented
  47. 47. class ManagerViewController: UIViewController, PanelManager { var panelContentWrapperView: UIView { return contentWrapperView } var panelContentView: UIView { return contentView } var panels: [PanelViewController] { return [fooPanelVC, barPanelVC] } } Protocol-oriented
  48. 48. Layout
  49. 49. Autoresizing
  50. 50. Autoresizing Struts & Springs
  51. 51. Auto Layout
  52. 52. Auto Layout • UIKit's anchor API
  53. 53. Auto Layout • UIKit's anchor API panelNavigationController.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true panelNavigationController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
  54. 54. Auto Layout • UIKit's anchor API • Don't forget isActive = true panelNavigationController.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true panelNavigationController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
  55. 55. Auto Layout • UIKit's anchor API • Don't forget isActive = true • Always creates new constraint instance panelNavigationController.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true panelNavigationController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
  56. 56. Auto Layout • UIKit's anchor API • Don't forget isActive = true • Always creates new constraint instance • Requires iOS 9.0+ panelNavigationController.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0).isActive = true panelNavigationController.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true panelNavigationController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
  57. 57. Open Source
  58. 58. Open Source • github.com/louisdh/panelkit
  59. 59. Open Source • github.com/louisdh/panelkit • Pull requests appreciated!
  60. 60. Open Source • github.com/louisdh/panelkit • Pull requests appreciated! • Complete history available
  61. 61. Open Source • github.com/louisdh/panelkit • Pull requests appreciated! • Complete history available • Versions are tagged
  62. 62. Open Source • github.com/louisdh/panelkit • Pull requests appreciated! • Complete history available • Versions are tagged • MIT license
  63. 63. Open Source Services
  64. 64. Travis CI • travis-ci.org
  65. 65. Travis CI • travis-ci.org • Build on every commit & PR
  66. 66. Travis CI • travis-ci.org • Build on every commit & PR • Run tests for every build
  67. 67. Travis CI • travis-ci.org • Build on every commit & PR • Run tests for every build • Result shown in GitHub UI
  68. 68. Travis CI • travis-ci.org • Build on every commit & PR • Run tests for every build • Result shown in GitHub UI • Free for open source projects!
  69. 69. Code Climate • codeclimate.com
  70. 70. Code Climate • codeclimate.com • Runs linter on every commit & PR
  71. 71. Code Climate • codeclimate.com • Runs linter on every commit & PR • Result shown in GitHub UI
  72. 72. Code Climate • codeclimate.com • Runs linter on every commit & PR • Result shown in GitHub UI • Free for open source projects!
  73. 73. Code Coverage • codecov.io
  74. 74. Code Coverage • codecov.io • Shows coverage of unit tests
  75. 75. Code Coverage • codecov.io • Shows coverage of unit tests • Gets results from Travis CI
  76. 76. Code Coverage • codecov.io • Shows coverage of unit tests • Gets results from Travis CI • Free for open source projects!
  77. 77. Open Source Distribution
  78. 78. Open Source Distribution Source
  79. 79. Open Source Distribution Source CocoaPods
  80. 80. Open Source Distribution Source CocoaPods Carthage
  81. 81. Open Source Distribution Source CocoaPods Carthage SPM
  82. 82. SPM
  83. 83. Swift Package Manager • Official dependency manager
  84. 84. Swift Package Manager • Official dependency manager • Included in Xcode
  85. 85. Swift Package Manager • Official dependency manager • Included in Xcode • Only for macOS currently
  86. 86. Swift Package Manager • Official dependency manager • Included in Xcode • Only for macOS currently • Open source
  87. 87. Swift Package Manager • Official dependency manager • Included in Xcode • Only for macOS currently • Open source • Written in Swift
  88. 88. Launch
  89. 89. Launch
  90. 90. Community response
  91. 91. Community response
  92. 92. Press
  93. 93. – John Gruber, Daring Fireball “It caught my eye a few weeks ago on Twitter, and now that I can play with it in an actual app, I’m even more impressed with the ingenuity.”
  94. 94. – Federico Viticci, MacStories “The best part, in my opinion, is that panels can be converted back to sidebars by snapping them to the edge of the display, which is a fantastic use of the iPad Pro's large screen.”
  95. 95. Other projects Colorcube
  96. 96. Colorcube featured App Store. July 22, 2016
  97. 97. Colorcube featured Apple Special Event. September 7, 2016.
  98. 98. Other projects Colorcube
  99. 99. Other projects Colorcube Pixure
  100. 100. Other projects Colorcube Pixure Leet Keyboard
  101. 101. Other projects Colorcube Pixure Leet Keyboard
  102. 102. Universal Apple Watch Quick Actions iCloud PanelKit Spotlight SearchLayers Blend modes Split View Slide Over Keyboard shortcuts iTunes File Sharing Photo Filter Bucket Fill Document import Document export Adobe Send to Desktop 3D-Touch Peek & Pop Share Sheet 200x Zoom
  103. 103. Universal Apple Watch Quick Actions iCloud PanelKit Spotlight SearchLayers Blend modes Split View Slide Over Keyboard shortcuts iTunes File Sharing Photo Filter Bucket Fill Document import Document export Adobe Send to Desktop 3D-Touch Peek & Pop Share Sheet 200x Zoom
  104. 104. Demo
  105. 105. What does Apple think of all this?
  106. 106. App Store. April 1, 2017
  107. 107. Featured! Pixure stats from 26 March to 6 April 2017
  108. 108. Summary • More powerful iPad UIs
  109. 109. Summary • More powerful iPad UIs • Written in Swift
  110. 110. Summary • More powerful iPad UIs • Written in Swift • Open source
  111. 111. Summary • More powerful iPad UIs • Written in Swift • Open source • Ready for production
  112. 112. Summary • More powerful iPad UIs • Written in Swift • Open source • Ready for production • Featured by Apple
  113. 113. Contact Louis D'hauwe louis@nextapps.be @LouisDhauwe
  114. 114. Questions?

×