20190117_iOSLT_CBLinSwift.pdf

E45f9c343d90c74554c65c89c6f861bc?s=47 shtnkgm
January 17, 2019

 20190117_iOSLT_CBLinSwift.pdf

Code-Based Layout in Swift

E45f9c343d90c74554c65c89c6f861bc?s=128

shtnkgm

January 17, 2019
Tweet

Transcript

  1. CBL in Swift Shota Nakagami

  2. Talking about "CBL"

  3. !

  4. CBL Code-Based layout

  5. I ! Code-Based Layout

  6. How to layout ? 4 StoryBoard 4 XIB 4 Code-BasedʢProgrammaticallyʣ

  7. Storyboard & XIB features 4 Ease of use ☺ 4

    Segue ☺ 4 Visual (multi device screen size) 4 Constraint Checker ☺ 4 Non-Reusable " 4 Hard to Resolve Conflict " 4 Hard to review (XML) "
  8. Testable? ! class ViewController: UIViewController { let dependency: Dependency //

    Dependency Injection with Initializer init(dependency: Dependency) { self.dependency = dependency } } 4 NG: Storyboard ☠ no initializer... 4 OK: XIB " 4 OK: CBL "
  9. CBL features 4 Reusable ☺ 4 Speedy ☺ 4 Easy

    to Resolve Conflict ☺ 4 Easy to Review ☺ 4 Cost of Learning " 4 Non-Visual "
  10. StoryBoard XIB Codebased ! Segue ✅ # Visual ✅ ✅

    $ Compiler Check ✅ ✅ % Testable (DI) ✅ ✅ ♻ Reusable ✅ ' Less Conflict ✅ ( Reviewable ✅
  11. 6 Tips for CBL

  12. 1. Initialization Closure 2. "Then" 3. Custom View Class 4.

    lazy var 5. "SnapKit" 6. UIStackView
  13. class ViewController: UIViewController { let priceLabel = UILabel() let imageView

    = UIImageView() override func viewDidLoad() { super.viewDidLoad() priceLabel.numberOfLines = 2 priceLabel.textColor = .red priceLabel.font = .boldSystemFont(ofSize: 14) imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true imageView.layer.cornerRadius = 4 // addSubview, AutoLayout... } }
  14. messy viewDidLoad...

  15. 1. Initialization Closure

  16. class ViewController: UIViewController { let priceLabel: UILabel = { let

    label = UILabel() label.numberOfLines = 2 label.textColor = .red label.font = .boldSystemFont(ofSize: 14) return label }() let imageView: UIImageView = { let view = UIImageView() view.contentMode = .scaleAspectFill view.clipsToBounds = true view.layer.cornerRadius = 4 return view }() override func viewDidLoad() { super.viewDidLoad() // addSubview, AutoLayout... } }
  17. viewDidLoad is clean, but...

  18. class ViewController: UIViewController { let priceLabel: UILabel = { //

    type annotation let label = UILabel() // renaming label.numberOfLines = 2 label.textColor = .red label.font = .boldSystemFont(ofSize: 14) return label // return }() let imageView: UIImageView = { // type annotation let view = UIImageView() // renaming view.contentMode = .scaleAspectFill view.clipsToBounds = true view.layer.cornerRadius = 4 return view // return }() override func viewDidLoad() { super.viewDidLoad() // addSubview, AutoLayout... } }
  19. 2. "Then" https://github.com/devxoul/Then

  20. class ViewController: UIViewController { let priceLabel = UILabel().then { $0.numberOfLines

    = 2 $0.textColor = .red $0.font = .boldSystemFont(ofSize: 14) } let imageView = UIImageView().then { $0.contentMode = .scaleAspectFill $0.clipsToBounds = true $0.layer.cornerRadius = 4 } override func viewDidLoad() { super.viewDidLoad() // addSubview, AutoLayout... } }
  21. 3. Custom View Class

  22. class ViewController: UIViewController { let priceLabel = PriceLabel() let imageView

    = ItemImageView() override func viewDidLoad() { super.viewDidLoad() } }
  23. private let captureButton = CaptureButton().then { $0.onTapped = { [weak

    self] in self?.camera.capture() } }
  24. private let captureButton = CaptureButton().then { $0.onTapped = { [weak

    self] in // Compile Error self?.camera.capture() // Compile Error } }
  25. 4. lazy var

  26. private lazy var captureButton = CaptureButton().then { $0.onTapped = {

    [weak self] in self?.camera.capture() // OK } }
  27. Codebased AutoLayout

  28. NSLayoutAnchor ? // addSubview, AutoLayout... view.addSubview(button) button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true button.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active

    = true button.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true button.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
  29. !

  30. 5. "SnapKit" https://github.com/SnapKit/SnapKit

  31. view.addSubview(button) // button.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true // button.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true //

    button.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true // button.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true button.snp.makeConstraints { $0.edges.equalToSuperview() }
  32. // readable button.snp.makeConstraints { $0.center.equalToSuperview() $0.size.equalTo(CGSize(width: 64, height: 64)) }

    // Support Safe Area tableView.snp.makeConstraints { $0.top.bottom.equalTo(view.safeAreaLayoutGuide) $0.leading.trailing.equalToSuperview() }
  33. 6. UIStackView

  34. UIStackView = Stack "Layouted" View Less Constraints ! stackView.addArrangedSubview(label) stackView.addArrangedSubview(imageView)

    stackView.addArrangedSubview(button) label.snp.makeConstraints { $0.height.equalTo(20) } button.snp.makeConstraints { $0.height.equalTo(60) }
  35. Summary

  36. CBL: Code-Based layout 4 Testable, Speedy, and Reusable 4 Use

    "6 Tips" to clean code When to Use 4 Use CBL for simple layout 4 Use XIB for complicated layout 4 Use StoryBoard for segue