$30 off During Our Annual Pro Sale. View Details »

iOS View Class Design Basic

iOS View Class Design Basic

Swift愛好会 vol.40

darquro

May 10, 2019
Tweet

More Decks by darquro

Other Decks in Programming

Transcript

  1. Re:valua t ion https://fril.jp/
    L ead & Delight User F irst Ownership Fail Smart
    J047JFXΫϥεઃܭجຊ
    .BZ BU4XJGUѪ޷ձWPM

    View Slide

  2. .PCJMF&OHJOFFS
    3BLVUFO JOD


    "CPVU.F
    EBSRVSP
    :VLJ,VSPEB

    !EBSRVSP !EBSRVSP

    View Slide

  3. View Slide



  4. ࠓ೔ͷςʔϚΛߟ͑ͨཧ༝

    View Slide



  5. 5BCMFPG$POUFOUT
    w 7JFXͷΫϥεઃܭʹ͓͚Δجຊ
    w ΧελϜ7JFXΛ࡞Δ্Ͱͷ5JQT

    View Slide




  6. View Slide



  7. ࣮૷ํ๏
    " 4UPSZCPBSE7JFX$POUSPMMFS

    View Slide



  8. ࣮૷ํ๏
    " 4UPSZCPBSE7JFX$POUSPMMFS
    'BU7JFX$POUSPMMFS
    # 4UPSZCPBSE7JFX$POUSPMMFS
    9*#7JFX

    View Slide

  9. "UPNJD%FTJHO


    View Slide



  10. "UPNJD%FTJHO
    w 6*σβΠϯʹ͓͚Δߟ͑ํ
    w ύʔπɺίϯϙʔωϯτΛ
    ࠷খ୯Ґ ݪࢠʣ͔Βߟ͑Δ
    IUUQBUPNJDEFTJHOCSBEGSPTUDPN

    View Slide



  11. "UPNJD%FTJHO
    IUUQBUPNJDEFTJHOCSBEGSPTUDPN
    ݪࢠ ෼ࢠ ༗ػ෺ ςϯϓϨʔτ ϖʔδ

    View Slide



  12. "UPNJD%FTJHO
    8BOUFEMZ5FDI#PPL
    ୈষJ04Ͱ࣮૷͢Δ"UPNJD%FTJHO
    IUUQTXXXXBOUFEMZDPNDPNQBOJFTXBOUFEMZQPTU@BSUJDMFT

    View Slide



  13. "UPNJD%FTJHO

    View Slide



  14. "UPNJD%FTJHO
    "UPNT
    ʢݪࢠʣ
    .PMFDVMFT
    ʢ෼ࢠʣ
    0SHBOJTNT
    ʢ༗ػ෺ʣ
    ૹྉࠐΈ

    View Slide



  15. "UPNJD%FTJHO
    1BHFT
    ʢϖʔδʣ
    5FNQMBUFT
    ʢςϯϓϨʔτʣ
    YYYY YYYY
    YYYY YYYY YYYY
    YYYY YYYY
    YYYY
    =
    YYY
    YYYYYYYYYYYYYYY
    YYY YYY
    YYYYYYYYYYYYYYY

    View Slide



  16. .PMFDVMFTʢ෼ࢠʣ
    .PMFDVMFTʢ෼ࢠʣ
    w 6**NBHF7JFX ݪࢠ
    ͱ

    6*-BCFM ݪࢠ
    ͕ਫฏʹฒͼɺ

    ؙ֯ͷ࿮ઢ ݪࢠ
    Λ࣋ͭ7JFX


    3PVOEFE$PSOFS8JUI*DPO-BCFM

    View Slide



  17. 0SHBOJTNTʢ༗ػ෺ʣ
    0SHBOJTNTʢ༗ػ෺ʣ
    w ෳ਺ͷ
    3PVOEFE$PSOFS8JUI*DPO-BC
    FM ෼ࢠ
    Λ

    ഑ஔ͢Δ͜ͱ͕Ͱ͖Δ7JFX

    View Slide



  18. 5FNQMBUFTʢςϯϓϨʔτʣ
    5FNQMBUFTʢςϯϓϨʔτʣ
    w Ͳ͜ΛมߋՄೳͱͳΔͷ͔
    w ΞΠίϯදࣔඇදࣔɺ৭
    w ςΩετ৭ɺαΠζ
    w ࿮ઢ༗ແɺଠ͞ɺ৭
    w എܠ৭
    YYY YYY YYY

    View Slide



  19. ͜͜·Ͱͷ·ͱΊ

    View Slide



  20. ͜͜·Ͱͷ·ͱΊ
    w 'BU7JFX$POUSPMMFSΛͳͨ͘ΊʹɺΧελϜ7JFXͰ
    ίʔυ෼཭͠Α͏
    w "UPNJD%FTJHOΛࢀߟʹ͠ͳ͕Βɺ7JFXΫϥεઃܭ
    Λߟ͑Α͏

    View Slide



  21. ͜͜·Ͱͷ·ͱΊ
    w ΞϓϦέʔγϣϯΛ࡞Δ্ͰͷҰൠతͳઃܭཧ࿦
    w ΞʔΩςΫνϟʔ .7$ .71 .77. $MFBO
    "SDIJUFDUVSF 3FEVY FUDʜ

    w σβΠϯύλʔϯ 'BDUPSZ 1SPUPUZQF
    4JOHMFUPO 0CTFSWFS FUDʜ

    View Slide



  22. ͜͜·Ͱͷ·ͱΊ
    w ΞϓϦέʔγϣϯΛ࡞Δ্ͰͷҰൠతͳઃܭཧ࿦
    w ΞʔΩςΫνϟʔ .7$ .71 .77. $MFBO
    "SDIJUFDUVSF 3FEVY FUDʜ

    w σβΠϯύλʔϯ 'BDUPSZ 1SPUPUZQF
    4JOHMFUPO 0CTFSWFS FUDʜ

    ੹຿ͷ෼཭

    View Slide



  23. ΧελϜ7JFXΛ࡞Δ্Ͱͷ5JQT

    View Slide



  24. ᶃ9*#ͰσβΠϯ͢Δ7JFX

    View Slide



  25. ᶃ9*#ͰσβΠϯ͢Δ7JFX
    extension NibLoadable where Self: UIView {
    static var nibName: String {
    return String(describing: self)
    }
    static func loadNib(_ bundle: Bundle? = nil) -> UINib {
    let bundle = bundle ?? Bundle.main
    return UINib(nibName: nibName, bundle: bundle)
    }
    func loadSubviewFromNib() {
    let nib = Self.loadNib(Bundle(for: type(of: self)))
    guard let subview = nib.instantiate(withOwner: self, options: nil).first as? UIView else {
    return
    }
    subviews.forEach { $0.removeFromSuperview() }
    addSubview(subview)
    setNeedsUpdateConstraints()
    }
    func fitConstraintsSubview() {
    if let contentView = subviews.first {
    contentView.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
    contentView.topAnchor.constraint(equalTo: self.topAnchor),
    contentView.leftAnchor.constraint(equalTo: self.leftAnchor),
    contentView.rightAnchor.constraint(equalTo: self.rightAnchor),
    contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
    ])
    }
    }
    }

    View Slide



  26. ᶃ9*#ͰσβΠϯ͢Δ7JFX
    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
    }
    override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
    }
    override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setup()
    }
    private func setup() {
    loadSubviewFromNib()
    }
    override func updateConstraints() {
    fitConstraintsContentView()
    super.updateConstraints()
    }

    View Slide



  27. ᶄ!*#%FTJHOBCMFɺ!*#*OTQFDUBCMFΛ࢖͏
    @IBDesignable final class RoundedCornerWithIconLabel: UIView {
    @IBInspectable var cornerRadius: CGFloat = -1
    @IBInspectable var borderColor: UIColor = ColorPalette.textGray
    @IBInspectable var borderWidth: CGFloat = 1
    @IBInspectable var text: String = "Label"
    @IBInspectable var textColor: UIColor = ColorPalette.textGray
    @IBInspectable var isImageShown: Bool = false
    @IBInspectable var image: UIImage?
    @IBInspectable var imageTintColor: UIColor = ColorPalette.textGray

    View Slide



  28. ᶄ!*#%FTJHOBCMFɺ!*#*OTQFDUBCMFΛ࢖͏
    @IBInspectable var text: String = "Label" {
    didSet {
    setText(text)
    }
    }
    private func setText(_ value: String) {
    label.text = value
    label.sizeToFit()
    }

    View Slide



  29. ᶅQSFQBSF'PS*OUFSGBDF#VJMEFSΛ࢖͏
    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
    }
    override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
    }
    override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setup()
    }
    private func setup() {
    loadSubviewFromNib()
    setCornerRadius(cornerRadius)
    setBorderColor(borderColor)
    setBorderWidth(borderWidth)
    setImageShown(isImageShown)
    setImage(image)
    setImageTintColor(imageTintColor)
    setTextColor(textColor)
    setText(text)
    setTextFontSize(textFontSize)
    }

    View Slide



  30. ᶆMB[ZWBS*OJUJBMJ[BUJPO$MPTVSFΛ࢖͏
    @IBDesignable final class ItemDetailItemSalesLabelsContainer: UIView {
    private lazy var includeCarriageLabel: UIView = {
    let label = RoundedCornerWithIconLabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
    label.labelType = ItemDetailItemSalesLabelType.includeCarriage
    label.backgroundColor = ColorPalette.lightOrange
    label.borderWidth = 0
    label.isImageShown = true
    label.image = FLFrilIcon.tagIcon(withSize: 14.0)
    .image(with: CGSize(width: 14.0, height: 14.0))
    .withRenderingMode(.alwaysTemplate)
    label.imageTintColor = ColorPalette.textWhite
    label.text = "ૹྉࠐΈ"
    label.textColor = ColorPalette.textWhite
    label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
    return label
    }()

    View Slide



  31. ᶇ0QUJPO4FUΛ࢖͏
    struct ItemDetailItemSalesLabelOptionSet: OptionSet {
    let rawValue: UInt8
    static let includeCarriage = ItemDetailItemSalesLabelOptionSet(rawValue: 1 << 0)
    static let excludeCarriage = ItemDetailItemSalesLabelOptionSet(rawValue: 1 << 1)
    static let anonymousCarriage = ItemDetailItemSalesLabelOptionSet(rawValue: 1 << 2)
    static let nowAvailable = ItemDetailItemSalesLabelOptionSet(rawValue: 1 << 3)
    }
    @IBDesignable final class ItemDetailItemSalesLabelsContainer: UIView {
    var labelSet: ItemDetailItemSalesLabelOptionSet = []
    }

    View Slide



  32. ͍͞͝ʹ
    ੹຿ͷ෼཭Λҙࣝͨ͠ઃܭͰɺݎ࿚ͳιʔείʔυΛ໨
    ࢦ͠·͠ΐ͏

    View Slide



  33. 5IBOLZPVGPSMJTUFOJOH

    View Slide