Ce diaporama a bien été signalé.
Le téléchargement de votre SlideShare est en cours. ×

Manual Layout Revisited

Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Publicité
Prochain SlideShare
Reactive cocoa
Reactive cocoa
Chargement dans…3
×

Consultez-les par la suite

1 sur 49 Publicité

Manual Layout Revisited

Télécharger pour lire hors ligne

A talk given at the Tokyo iOS Meetup on November 18th, 2017. It explains why, after about two years of being a strong Auto Layout advocate, I am drifting back to manual layout. This progression happened because, after finding a layout that was difficult to achieve with Auto Layout and resorting to manual layout in one specific case, I found that, by writing some very simple functions, I could achieve many of the same layouts as Auto Layout with a similar code size.

A talk given at the Tokyo iOS Meetup on November 18th, 2017. It explains why, after about two years of being a strong Auto Layout advocate, I am drifting back to manual layout. This progression happened because, after finding a layout that was difficult to achieve with Auto Layout and resorting to manual layout in one specific case, I found that, by writing some very simple functions, I could achieve many of the same layouts as Auto Layout with a similar code size.

Publicité
Publicité

Plus De Contenu Connexe

Similaire à Manual Layout Revisited (20)

Publicité

Plus récents (20)

Manual Layout Revisited

  1. 1. ...ifthere'sonethingiOScommunitydoes notlackareattemptstorewriteoreven entirelyreplaceAutoLayout....
  2. 2. IconsiderAutoLayoutoneofthetop5, maybetop3technologiestoevercomeout ofApple.It'sbeautiful,easytoworkwith andthere'snothingIcan'tdowithit.It's Apple'schoiceforUIlayoutandyoushould masterit,notavoidit. —Aleksandar Vacić,http://aplus.rs/2017/much-ado-about-ios-app- architecture/
  3. 3. ...
  4. 4. UIKitAutoLayoutandInterfaceBuilderare notsupportedbyTexture[anopensource project].Itisworthnotingthatbothofthese technologiesarenotpermittedinestablished anddisciplinediOSdevelopmentteams,such asatFacebook,Instagram,andPinterest. —http://texturegroup.org/docs/faq.html#texture-does-not-support-uikit- auto-layout-or-interfacebuilder
  5. 5. ...
  6. 6. Ishavedthousandsoflinesofboilerplate byleveragingAutoLayout.Many developersstillinsistonmanuallayout. Maybetheydon'tunderstandAuto- Layout,ormaybetheyheardastoryfrom afriendofafriendabouthowAuto-Layout isslow.(Itisn't.)
  7. 7. I'veseentoomanydevelopers—especially atlargecompanies—inventin-house layoutengine.That'sjustnuts.Don'tbloat yourappwithabespokeframeworkwhen Applebundlesafinelayoutenginewith theOS. —Ben Sandofsky,https://blog.halide.cam/one-weird-trick-to-lose-size- c0a4013de331
  8. 8. ...
  9. 9. ...SinceiOS8,wecanuseautomatic heightcalculationwithoutimplementing mentionedmethodatthedelegateof UITableView.Toachievethisyoumayuse AutoLayouttoolandrowHeightvariable settoUITableViewAutomaticDimension...
  10. 10. Despitetheabilitytousethesetools,I stronglyrecommendyoudonot.Andmore  — Irecommendnotusingevencomplex mathcalculationsonyourwaytodefine furtherheightofacell,onlyaddition, subtraction,multiplicationanddivision(if possible).
  11. 11. ButwhataboutAutoLayout?Isitreallysoslowas Iwastalkingabout?Probablyyouwillbe surprisedbutit'struth.Incrediblyslowifyouwant seeperfectsmoothscrollinginyourapponall actualdeviceswhichhavelonglifecycle(especially comparedtoAndroiddevices).Andmoresubviews youhave,lessquicklyAutoLayoutworks. —Alexander Orlov,https://medium.com/ios-os-x-development/perfect-smooth- scrolling-in-uitableviews-fd609d5275a5
  12. 12. Manual Layout Revisited
  13. 13. Everyone needs to handle layout.
  14. 14. Apps are different.
  15. 15. Non-engineering factors also matter.
  16. 16. view1.frame = CGRect(x: 0, y: 100, height: 32, width: 320) view2.frame.origin.x = 0 view2.frame.origin.y = view1.frame.origin.y + view1.frame.size.height + 10 view2.frame.size.width = 100 view2.frame.size.height = view.frame.size.height - view1.frame.size.height - 10 view3.frame.origin.x = view2.center - view2.frame.width / 4 view3.frame.origin.y = view2.frame.origin.y view3.frame.size.width = view2.frame.width / 2 view3.frame.size.height = view2.frame.origin.y view4.frame.origin.x = view3.center - view3.frame.width / 4 view4.frame.origin.y = view3.frame.origin.y view4.frame.size.width = view3.frame.width / 2 view4.frame.size.height = view3.frame.origin.y
  17. 17. Auto layout made me reconsider how I write manual layout.
  18. 18. Manual layout operations can be easily consolidated into simple functions.
  19. 19. Manual Layout Operations — Add convenience methods to simplify code
  20. 20. Manual Layout Operations — Add convenience methods to simplify code — Apply changes to collections of views at the same time
  21. 21. Manual Layout Operations — Add convenience methods to simplify code — Apply changes to collections of views at the same time — Arrange a collection of views in a particular order
  22. 22. Manual Layout Operations — Add convenience methods to simplify code — Apply changes to collections of views at the same time — Arrange a collection of views in a particular order — Resize one view to make a collection fit on the screen
  23. 23. Creating Convenience Methods These are extensions that simplify reasoning about layout code.
  24. 24. Creating Convenience Methods extension UIView { var bottom: CGFloat { get { return frame.maxY } set(newValue) { frame.origin.y = newValue - frame.height } } } // ... myView.bottom = 100
  25. 25. Creating Convenience Methods extension UIView { var bottomRightCorner: CGPoint { get { return CGPoint(x: frame.maxX, y: frame.maxY) } set(newValue) { frame.origin = CGPoint( x: newValue.x - frame.size.width, y: newValue.y - frame.size.height ) } } }
  26. 26. Demo
  27. 27. Creating Operations on Collections of Views Applying the methods above to an array of views is a useful way to reduce code.
  28. 28. Creating Operations on Collections of Views func resize(views: [UIView], withWidth width: CGFloat) { views.forEach { view in view.width = width } }
  29. 29. Creating Operations on Collections of Views func reposition(views: [UIView], withLeft left: CGFloat) { views.forEach { view in view.left = left } }
  30. 30. Demo
  31. 31. Arranging Horizontally or Vertically It is common to arrange views along an axis (consider UIStackView).
  32. 32. Arranging Horizontally or Vertically func arrangeTopToBottom(views: [UIView]) { guard var currentPosition = views.first?.top else { return } for view in views { view.top = currentPosition currentPosition += view.height } }
  33. 33. Resizing to Fit On Screen Most of the time,a layout design will fit into two cases: — The layout is not intended to fit on the screen.Usually this type of layout will be placed inside a UIScrollView or one of its subclasses. — The layout is intended to fit on the screen.
  34. 34. Resizing to Fit On Screen For the second case—in a surprising number of instances—the layout can be achieved by simply resizing a single view so that its height fills whatever space is left by the other views.
  35. 35. Resizing to Fit On Screen func resize(view: UIView, in views: [UIView], toFitHeight height: CGFloat) { let heightOfViews = views.reduce(CGFloat(0)) { memo, currentView in guard view != currentView else { return memo } var mutableMemo = memo mutableMemo += view.height return mutableMemo } view.height = height - heightOfViews }
  36. 36. Resizing to Fit On Screen func resize(views:[UIView], toFitHeight height: CGFloat) { views.forEach { view in view.height = height / CGFloat(views.count) } }
  37. 37. Resizing to Fit On Screen — There are a lot of potential resizing functions. — Resizing also requires considering potential error cases.Can you guarantee that the content will fit?
  38. 38. Demo
  39. 39. What about...? — Top or bottom margins
  40. 40. What about...? — Top or bottom margins — Spacing between the elements
  41. 41. What about...? — Top or bottom margins — Spacing between the elements — Sizing UILabels or UITextViews to fit their content
  42. 42. What about...? — Top or bottom margins — Spacing between the elements — Sizing UILabels or UITextViews to fit their content — Aligning to the first or last baseline text
  43. 43. What about...? — Top or bottom margins — Spacing between the elements — Sizing UILabels or UITextViews to fit their content — Aligning to the first or last baseline text — Sizing UIImageViews to preserve their aspect ratio
  44. 44. What about...? — Top or bottom margins — Spacing between the elements — Sizing UILabels or UITextViews to fit their content — Aligning to the first or last baseline text — Sizing UIImageViews to preserve their aspect ratio
  45. 45. What about...? — Top or bottom margins — Spacing between the elements — Sizing UILabels or UITextViews to fit their content — Aligning to the first or last baseline text — Sizing UIImageViews to preserve their aspect ratio — Leading and trailing rather than left and right
  46. 46. These methods are just an introduction.

×