Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Auto Layout with an extended Visual Format Language

Auto Layout with an extended Visual Format Language

AltConf19 on Thursday 11:00-11:10 (LT) at San Jose Marriott
http://altconf.com

Video Archive: https://www.youtube.com/watch?v=3n3AeUuWavw

ばんじゅん🍓

June 06, 2019
Tweet

More Decks by ばんじゅん🍓

Other Decks in Programming

Transcript

  1. Copyright © ZOZO Technologies, Inc. All Rights Reserved. ;0;05FDIOPMPHJFT *OD

    #"/+VO!CBOKVO "VUP-BZPVUXJUIBOFYUFOEFE 7JTVBM'PSNBU-BOHVBHF "MU$POG
  2. Copyright © ZOZO Technologies, Inc. All Rights Reserved. 4QFBLFS1SPGJMF ;0;05FDIOPMPHJFT

    *OD %FWFMPQNFOU%JWJTJPO #"/+VO!CBOKVO -PWF-JWFS NBD04  $SFBUF-JWF1IPUPTGSPN.PWJFT 'MJDL4,, J04 
 +BQBOFTF$VTUPN,FZCPBSE&YUFOTJPO 4JEF1SPKFDUT
  3. Copyright © ZOZO Technologies, Inc. All Rights Reserved. w 5IFMBSHFTUGBTIJPOPOMJOFTIPQQJOHXFCTJUFJO+BQBO

    w 0WFS TUPSFTP⒎FSJOHNPSFUIBO CSBOET "TPG%FDTU    w "UBOZHJWFOUJNF NPSFUIBO JUFNTBSFBWBJMBCMFGPSQVSDIBTF  JOBEEJUJPOPGNPSFUIBO OFXJUFNT BWFSBHF QFSEBZ w 4BNFEBZEFMJWFSZTFSWJDFTBSFBWBJMBCMFJOMJNJUFEBSFBTXJUIJO+BQBO IUUQT[P[PKQ
  4. Copyright © ZOZO Technologies, Inc. All Rights Reserved. "VUP-BZPVUXJUI7'- Pros

    Multiple constraints at once, using a compact expression ASCII-art like, readable diff Create only valid constraints "H:|-[icon(==32)]-[label]-(>=8)—|"
  5. Copyright © ZOZO Technologies, Inc. All Rights Reserved. "VUP-BZPVUXJUI7'- Cons

    VFL itself is not validated at compile time Needs some boilerplates to use No explicit support for neither Layout Margins or Safe Area
  6. Copyright © ZOZO Technologies, Inc. All Rights Reserved. override func

    loadView() { super.loadView() let views = [ "icon": iconView, "name": nameLabel] views.values.forEach { view.addSubview($0) $0.translatesAutoresizingMaskIntoConstraints = false } let metrics = ["p": 8] view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-p-[icon(==64)]", options: [], metrics: metrics, views: views)) view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: iconView nameLabel 1. setup a view hierarchy for views
 2. enable auto-layout for views Copyright © ZOZO Technologies, Inc. All Rights Reserved. "VUP-BZPVUŠXJUIPVU/PSUI-BZPVU
  7. Copyright © ZOZO Technologies, Inc. All Rights Reserved. override func

    loadView() { super.loadView() let views = [ "icon": iconView, "name": nameLabel] views.values.forEach { view.addSubview($0) $0.translatesAutoresizingMaskIntoConstraints = false } let metrics = ["p": 8] view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-p-[icon(==64)]", options: [], metrics: metrics, views: views)) view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-p-[name]-p-|", options: [], metrics: metrics, views: views)) view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-100-[icon(==64)]-p-[name]", options: [], metrics: metrics, views: views)) } 3. write VFL with many parameters
  8. Copyright © ZOZO Technologies, Inc. All Rights Reserved. /PSUI-BZPVU6TBHF 1.

    declare views 2. write VFLs autolayout("…") iconView nameLabel override func loadView() { super.loadView() let autolayout = northLayoutFormat(["p": 8], [ "icon": iconView, "name": nameLabel]) autolayout("H:|-p-[icon(==64)]") autolayout("H:|-p-[name]-p—|") autolayout("V:|-p—[icon(==64)]-p-[name]") }
  9. Copyright © ZOZO Technologies, Inc. All Rights Reserved. 7'-4BGF"SFB VFL

    does not support Safe Area But I want to write constraints as easy as VFL
  10. Copyright © ZOZO Technologies, Inc. All Rights Reserved. &YUFOEJOH7'- Idea

    VFL (Apple) Extended VFL (EVFL) autolayout("H:|[header]|") autolayout("H:||[icon]… single vertical bar | = superview bounds double vertical bars || = layout margin bounds
  11. Copyright © ZOZO Technologies, Inc. All Rights Reserved. &YUFOEJOH7'- Idea

    VFL (Apple) Extended VFL (EVFL) autolayout("H:|[header]|") autolayout("H:||[icon]… single vertical bar | double vertical bars ||
  12. Copyright © ZOZO Technologies, Inc. All Rights Reserved. 8IZ-BZPVU.BSHJOT Layout

    Margins follow Safe Area Layout Margins are active on all devices not only devices with home indicator test layout constraints in any devices
  13. Copyright © ZOZO Technologies, Inc. All Rights Reserved. -BZPVU.BSHJOT4BGF"SFB Example

    Constraining to Layout Margins No constraints ref to Safe Area Layout Margins reflects Safe Area Copyright © ZOZO Technologies, Inc. All Rights Reserved.
  14. Copyright © ZOZO Technologies, Inc. All Rights Reserved. *NQMFNFOUJOH&7'- EVFL

    Parser AST "H:||[icon]… struct VFL Edge Constraints "H:[icon]… Auto Layout Decomposer +
  15. Copyright © ZOZO Technologies, Inc. All Rights Reserved. 1BSTJOH&7'- EVFL

    Parser AST "H:||[icon]… struct parser combinator (kareman/FootlessParser)
  16. Copyright © ZOZO Technologies, Inc. All Rights Reserved. &7'-"CTUSBDU4ZOUBY5SFF struct

    VFL { let orientation: Orientation let firstBound: (Bound, Connection)? let firstView: View let views: [(Connection, View)] var lastView: View {return views.last?.1 ?? firstView} let lastBound: (Connection, Bound)?
  17. Copyright © ZOZO Technologies, Inc. All Rights Reserved. &7'-"CTUSBDU4ZOUBY5SFF enum

    Orientation {case h, v} struct View { let name: String let predicateListWithParens: [Predicate] } enum Bound: String { case superview = "|" case layoutMargin = "||" }
  18. Copyright © ZOZO Technologies, Inc. All Rights Reserved. &7'-"CTUSBDU4ZOUBY5SFF enum

    Orientation {case h, v} struct View { let name: String let predicateListWithParens: [Predicate] } enum Bound: String { case superview = "|" case layoutMargin = "||" }
  19. Copyright © ZOZO Technologies, Inc. All Rights Reserved. 1BSTJOH&7'- static

    var parser: Parser<Character, VFL> { let metricName = identifier let positiveNumber: Parser<Character, CGFloat> = numberPa let simplePredicate: Parser<Character, VFL.SimplePredicat let predicateListWithParens: Parser<Character, [VFL.Predi <^> (char("(") *> ({[$0]} <^> VFL.Predicate.parser)) <*> zeroOrMore(char(",") *> VFL.Predicate.parser) <* let predicateList: Parser<Character, VFL.PredicateList> = <|> {.predicateListWithParens($0)} <^> predicateListW let bound: Parser<Character, VFL.Bound> = {_ in VFL.Bound <|> {_ in .superview} <^> string(VFL.Bound.superview. let connection = (VFL.Connection.init) <^> (char("-") *> <|> {_ in VFL.PredicateList.simplePredicate(.positive
  20. Copyright © ZOZO Technologies, Inc. All Rights Reserved. 1BSTJOH&7'- <|>

    {_ in VFL.PredicateList.simplePredicate(.positiveN <|> {_ in VFL.PredicateList.simplePredicate(.positiveN let view = curry(VFL.View.init) <^> (char("[") *> identifier) <*> optional(predicateListWithParens, otherwise: []) < let views = zeroOrMore({a in {(a, $0)}} <^> connection <*> let orientation: Parser<Character, VFL.Orientation> = {_ i <|> {_ in .h} <^> (string("H:") <|> string("")) return curry(VFL.init) <^> orientation <*> optional(tuple <^> bound <*> connection) <*> view <*> views <*> optional(tuple <^> connection <*> bound) }
  21. Copyright © ZOZO Technologies, Inc. All Rights Reserved. .JOJNVN%JGGGPS4BGF"SFB4VQQPSU double

    vertical bars || = stick to layout margin single vertical bar |-p- = stick to superview with a space p