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

UIColor Anatomy

UIColor Anatomy

iOSDC Japan 2020 #iosdc
「大解剖!UIColorファミリー」発表資料です。

https://fortee.jp/iosdc-japan-2020/proposal/8617aa4c-5386-4629-abf4-3e93ebfe2962

Shigure Shimotori

September 21, 2020
Tweet

More Decks by Shigure Shimotori

Other Decks in Programming

Transcript

  1. @S_Shimotori
    େղ๤ʂUIColorϑΝϛϦʔ
    iOSDC Japan 2020

    View Slide

  2. ͠΋ͱΓ
    • @S_Shimotori_pub

    • iOSΉ͔͍ͣ͠
    2

    View Slide

  3. UIColor ϑΝϛϦʔ
    ???
    3

    View Slide

  4. UIColorͱαϒΫϥεͨͪ
    4

    View Slide

  5. UIColor͸େՈ଒ͩͬͨʂ
    UIColor
    5

    View Slide

  6. ࠓճ࿩͢ωλ
    • UIColorʹ͸αϒΫϥε͕͍ͬͺ͍ʂ

    • αϒΫϥε঺հ

    • UIColorͷαϒΫϥεࣗ࡞͸݁ߏ೉͍͠ɻ

    • UIColorͷϝιουͷڍಈΛݟΔ
    6

    View Slide

  7. UIColorʹ͸
    αϒΫϥε͕͍ͬͺ͍ʂ
    7

    View Slide

  8. ͔ΜͨΜver.
    private
    8

    View Slide

  9. αϒΫϥε͕͍ͬͺ͍͋Δཧ༝
    UIColor͸ͱͯ΋ෳࡶ͔ͩΒ
    9

    View Slide

  10. UIColor
    var red: CGFloat

    var green: CGFloat

    var blue: CGFloat
    ม׵?
    init(white:alpha:)

    init(cgColor:)

    10

    View Slide

  11. ͲͷΑ͏ʹ৭σʔλΛอ࣋͢Δ͔ʁ
    • ͋ΒΏΔ৭σʔλΛಉ͡ܗࣜͰอ࣋͢Δͷ͸ແཧͦ͏

    • UIImageΛίϯϙʔωϯτ஋ʹม׵͸ແཧ

    • ৭ۭؒΛἧ͑Α͏ͱͯ͠ແҋʹม׵ͨ͠Βѻ͍ʹͦ͘͏

    • dynamic colorͷ৔߹͸traitʹԠͯࣗ͡༝ʹมΘΔ
    ৭Λܾఆ͢ΔͨΊͷσʔλΛͦͷ··͓͔࣋ͬͯ͘͠ͳ͍ʂ
    11

    View Slide

  12. ΋͠UIColor͕୯ମͰଘࡏ͍ͯͨ͠Β(1/2)
    class UIColor {
    private let redComponent: CGFloat?
    private let greenComponent: CGFloat?
    private let blueComponent: CGFloat?
    private let whiteComponent: CGFloat?
    private let alphaComponent: CGFloat?
    private let provider: ((UITraitCollection) -> UIColor)?
    private let image: UIImage?

    以下略
    12

    View Slide

  13. ΋͠UIColor͕୯ମͰଘࡏ͍ͯͨ͠Β(2/2)
    func withAlphaComponent() -> UIColor {

    if /*RGBで表現されているとき*/ {
    } else if /*色空間がdisplay P3のとき*/ {
    } else if /*パターンイメージを使うとき*/ {
    } else if /*dynamic colorのとき*/ {

    以下略
    13

    View Slide

  14. UIColorͷ࠾ͬͨղܾࡦ
    σβΠϯύλʔϯɿClass Cluster
    ʢAbstract Factoryͷ೿ੜʣ
    14

    View Slide

  15. σβΠϯύλʔϯͷ؍఺͔Β
    ←ந৅Ϋϥεɹ݉ɹΠϯελϯεͷੜ੒܎
    18ݸͷαϒΫϥεͦΕͧΕͰ

    18௨Γͷ۩ମతͳॲཧΛ࣮૷
    15

    View Slide

  16. Class Clusterͷ͕͍͜͜͢͝ʂ
    • ΫϥεΛ࢖͏ଆ͸಺෦࣮૷Λؾʹ͠ͳͯ͘Α͍

    • εʔύʔΫϥεUIColor͚ͩ஌͍ͬͯΕ͹े෼

    • αϒΫϥε͕ෳࡶͳ࣮૷Λ෼୲ͯ͘͠ΕΔ

    • ྫɿRGB୲౰ɺύλʔϯΠϝʔδ୲౰ɺAsset Catalog୲౰etc…
    16

    View Slide

  17. ࣮ࡍͷUIColor͸͜Μͳײ͡ʁ
    UIColor
    public init(red: CGFloat, ..., alpha: CGFloat) { return UIDeviceRGBColor() }

    public init(patternImage: CGFloat) { return UIDynamicPatternColor() }

    var cgColor: CGColor { get }
    UIDeviceRGBColor UIDynamicPatternColor
    let redComponent: CGFloat
    override var cgColor: CGColor {
    /*適切な処理*/
    }
    let image: UIImage
    override var cgColor: CGColor {
    /*適切な処理*/
    }
    RGB୲౰ ύλʔϯΠϝʔδ୲౰
    17
    ஫ɿਖ਼֬Ͱ͸͋Γ·ͤΜ

    View Slide

  18. ৭ͷܾఆํ๏͕͍ͬͺ͍ʂ
    • init(white:alpha:)

    • init(red:green:blue:alpha:) / init(hue:saturation:brightness:alpha:)

    • init(displayP3Red:green:blue:alpha:)

    • init(named:) / init(named:in:compatibleWith:)

    • init(dynamicProvider:)

    • init(ciColor:)

    • init(cgColor:)

    • init(patternImage:)

    • init(_:) ※SwiftUI.ColorɻiOS14.0ʙ
    શ෦ҧ͏αϒΫϥε͕ฦͬͯ͘Δ
    ʢ΋ͪΖΜݟ͔͚͸public class UIColorʣ
    18
    గਖ਼ʢ2020/09/20ʣ

    init(_:)͸طଘͷΫϥεΛฦ͢໛༷ɻ

    View Slide

  19. UIColorͷαϒΫϥε͸΋ͬͱ͍ͬͺ͍ʂ
    • ΠχγϟϥΠβ͕8छ10ݸʢiOS13.6࣌఺ʣ

    • init()΋ೖΕͨΒ9छ11ݸ

    • αϒΫϥε͕18ݸʢiOS13.6࣌఺ʣ
    iOS14Ͱ͸init(_:)͕૿͑ͯΔͷͰɺΠχγϟϥΠβ͕10छ12ݸɺαϒΫϥε͕19ݸʹͳ͍ͬͯΔ͔΋͠Εͳ͍ɻ
    19
    గਖ਼ʢ2020/09/20ʣ

    init(_:)͸طଘͷΫϥεΛฦ͢໛༷ɻ૿͑ͯͳ͍Έ͍ͨͰ͢ɻ

    View Slide

  20. αϒΫϥε঺հ
    20

    View Slide

  21. ͦͷલʹɿUIColorͷཪଆΛ࡯͢Δखஈ
    • class-dump

    • Objective CͷϔομΛ೷͚Δπʔϧ

    • Method swizzlingɺXcodeͷSymbolic Breakpoint

    • ಛఆͷϝιου͕ݺ͹ΕͨॠؒΛั·͑Δ

    • ԿΛ͍ͯ͠Δ͔΋ͪΐͬͱΘ͔Δ

    • object_getClass(_:)

    • ܕ໊ͷऔಘ

    • type(of:)ͩͱ͏·͘औΕͳ͍
    21

    View Slide

  22. class-dumpͰ೷͍ͯΈͨ
    UIKitCore.framework/UIDeviceRGBColor.hʢҰ෦ൈਮʣ
    #import

    __attribute__((visibility("hidden")))
    @interface UIDeviceRGBColor : UIColor
    {
    double redComponent;
    double greenComponent;
    double blueComponent;
    double alphaComponent;
    struct CGColor *_cachedColor;
    }

    - (_Bool)getWhite:(double *)arg1 alpha:(double *)arg2;
    Copyright (C) 1997-2019 Steve Nygard.
    22

    View Slide

  23. αϒΫϥεΛछྨ෼͚͢Δͱ͜Μͳײ͡

    dynamic color

    ίϯϙʔωϯτ஋Ͱ

    ৭Λܾఆ
    ଞFrameworkͱͷ࿈ܞ
    ϓϨʔεϗϧμʔ
    23

    View Slide

  24. 1. UIPlaceholderColor
    • init()ͰಘΒΕΔΫϥε

    • init()Ͱ͑͞UIColorΛฦ͞ͳ͍

    • Կ͔ಛఆͷ৭Λࢦ͍ͯ͠ΔΘ͚Ͱ͸ͳ͍
    24

    View Slide

  25. Nextɿίϯϙʔωϯτ஋Λѻ͏αϒΫϥε

    ίϯϙʔωϯτ஋Ͱ

    ৭Λܾఆ
    25

    View Slide

  26. 2-3. UI(Cached)DeviceRGBColor
    • RGBͰࢦఆ͞ΕΔ৭ͷͨΊͷΫϥε

    • RGBAίϯϙʔωϯτ஋Λड͚औΓɺอ͓࣋ͯ͘͠

    • init(red:green:blue:alpha:)Ͱ࡞ͬͨͱ͖͸UIDeviceRGBColor

    • init(hue:saturation:brightness:alpha:)΋͜Ε

    • UIColor.red΍UIColor.green͸UICachedDeviceRGBColor

    • Apple͕༻ҙͯ͘͠ΕͨRGBͷ৭ͷ͏ͪɺstatic colorͰ͋Δ΋ͷ
    26

    View Slide

  27. CachedͳΫϥεͱ͸
    • ͦͷ໊ͷ௨Γɺ࢖͍ճͨ͢ΊͷΫϥε

    • ࢀরΧ΢ϯτ΍copyͷ͋ͨΓΛௐ੔͍ͯ͠ΔΈ͍ͨ

    • ྫɿUIColor.blue΍UIColor.white

    • Ұ෦ͷαϒΫϥεͷΈ͕αϒΫϥεUICached???ColorΛ࣋ͭ
    27

    View Slide

  28. 4-5. UI(Cached)DeviceWhiteColor
    • άϨʔεέʔϧͳ৭͸ͬͪ͜

    • WhiteͱAlphaͷ஋Λड͚औΓɺอ͓࣋ͯ͘͠

    • init(white:alpha:)ͳΒUIDeviceWhiteColor

    • UIColor.white΍UIColor.clearͳΒUICachedDeviceWhiteColor
    28

    View Slide

  29. 6. UIDisplayP3Color
    • init(displayP3Red:green:blue:alpha:)ͰಘΒΕΔ

    • ৭ۭ͕ؒdisplay P3ͳ৭͸͜Ε
    29

    View Slide

  30. Nextɿdynamic color

    dynamic color
    30

    View Slide

  31. 7. UIDynamicColor
    • dynamic colorͷ௖఺

    • iOSʹ͓͍ͯdynamicͱ͸ʮtraitͷมԽʹԠͯ͡ಈతʹมΘΔʯͱ͍͏͜ͱ

    • var _isDynamic: Bool { get } ͕ਅ

    • ͜Ε͕ਅͳΒ͹traitͷมԽʹ௥ै͢ΔΒ͍͠
    31

    View Slide

  32. 8. UIDynamicSystemColor
    • Standard Colorͷ͏ͪɺdynamic colorͰ͋Δ΋ͷ

    • UIColor.systemBlue΍UIColor.systemBackgroundͳͲ
    32

    View Slide

  33. 9. UIDynamicCatalogColor
    • Asset Catalog init(named:) ͔ΒಘΒΕΔ

    • 1ͭͰ΋Dark ModeରԠͷ৭Λ࡞ͬͯ͋Δͱશͯͷ৭͕͜ͷΫϥεͰදݱ͞ΕΔ

    ʢstatic color͔͠ͳ͍৔߹͸static color༻ͷΫϥεΛ࢖͍෼͚Δʣ
    33

    View Slide

  34. 10. UIDynamicPatternColor
    • init(patternImage:)ͰಘΒΕΔΫϥε

    • ಺෦ʹUIImageΛ࣋ͭ

    • traitͷมԽʹԠͯ͡UIImage಺ͷը૾Λ࢖͍෼͚Δ
    34

    View Slide

  35. 11. UIDynamicProviderColor
    • init(dynamicProvider:)ͰಘΒΕΔ

    • ༩͑ͨproviderϒϩοΫΛอ͍࣋ͯ͠Δ
    35

    View Slide

  36. 12. UIDynamicAppDefinedColor
    • ରԠ͢ΔΠχγϟϥΠβ͸ͳ͠

    • ྫ͑͹UIDynamicProviderColorΛarchive & unarchive͢Δͱ͜ͷܕʹͳΔ

    • [UITraitCollection: UIColor] ͷ͔ͨͪͰه࿥͢Δ

    • ଞʹ΋ಇ͍͍ͯΔͱ͜Ζ͕͋ͬͨΒڭ͍͑ͯͩ͘͞
    36

    View Slide

  37. 13. UIDynamicModifiedColor
    • ରԠ͢ΔΠχγϟϥΠβ͸ͳ͠

    • ಺෦ʹUIDynamicColorΛ1ͭɺalpha componentΛ1ͭ࣋ͭ

    • ޙड़
    37

    View Slide

  38. NextɿଞͷFrameworkͱ࿈ܞ͢ΔαϒΫϥε
    ଞFrameworkͱͷ࿈ܞ
    38

    View Slide

  39. 14. UICIColor
    • init(ciColor:)ͰಘΒΕΔΫϥε

    • CIColorΛड͚औͬͯอ࣋͢Δ͔ΒUICIColor

    • CI = CoreImage.framework

    • ड͚औͬͨCIColorΛ಺෦ʹӅ͍࣋ͬͯ͠Δ

    • var ciColor: CIColor { get } ͸ͦͷ··ฦ͚ͩ͢ͷॲཧΛ͍ͯ͠ΔΈ͍ͨ
    39

    View Slide

  40. 15. UICGColor
    • init(cgColor:)ͰಘΒΕΔΫϥε

    • ಺෦ʹCGColorΛӅ͍࣋ͬͯ͠Δ

    • var cgColor: CGColor { get } ͸ͦͷ··ฦ͚ͩ͢

    • UICGColor͸αϒΫϥεΛ࣋ͭ
    40

    View Slide

  41. 16-17. UI(Cached)PatternCGColor
    • init(cgColor:)ͰಘΒΕΔΫϥεͦͷ2

    • PatternͳCGColorͷͨΊͷΫϥε

    • ڪΒ͘ var pattern: CGPattern? { get } Λ͍࣋ͬͯΔΑ͏ͳCGColor

    • खͬऔΓૣ͍ྫɿUIColor.init(cgColor: UIColor.init(patternImage: image).cgColor)

    • CachedΫϥεΛ࣋ͭʢUICachedPatternCGColorʣ
    41

    View Slide

  42. UIPatternCGColorΛ࡞Δ
    let drawPattern: CGPatternDrawPatternCallback = { info, context in
    let subunit = CGFloat(20.0)
    context.setFillColor(red: 0.5, green: 0, blue: 0, alpha: 1)
    context.fill(CGRect(x: 0, y: 0, width: subunit, height: subunit))
    context.setFillColor(red: 1, green: 0.3, blue: 0.3, alpha: 1)
    context.fill(CGRect(x: subunit, y: subunit, width: subunit, height: subunit))
    context.setFillColor(red: 0.7, green: 0.3, blue: 0, alpha: 1)
    context.fill(CGRect(x: 0, y: subunit, width: subunit, height: subunit))
    context.setFillColor(red: 0.7, green: 0.3, blue: 0, alpha: 1)
    context.fill(CGRect(x: subunit, y: 0, width: subunit, height: subunit))
    }
    var callbacks = CGPatternCallbacks(version: 0, drawPattern: drawPattern, releaseInfo: nil)
    let pattern = CGPattern(info: nil, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), matrix:
    CGAffineTransform(a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0), xStep: 40, yStep: 40,
    tiling: .constantSpacing, isColored: true, callbacks: &callbacks)!

    let color = UIColor(cgColor: CGColor(patternSpace: CGColorSpace(patternBaseSpace: nil)!, pattern:
    pattern, components: [1, 1, 1, 1])!)
    ਺ࣈ͸ద౰Ͱ͢
    42

    View Slide

  43. UICachedPatternCGColorΛ୳͍ͯ͠·͢
    ಇ͍͍ͯΔͱ͜ΖΛݟ͔͚ͨํ͸@S_Shimotori_pub·Ͱʂ
    UICached

    PatternCGColor
    ※ಛʹँྱ͸ͳ͍Ͱ͢
    43

    View Slide

  44. 18. NSColor
    • UIKit.NSColor.init(coder:)ʹΑΓCocoa.NSColorΛunarchiveͰ͖Δ

    • UIColorΛσίʔυ͢Δͱ͖͸ݺ͹Εͳ͍Έ͍ͨ

    • ࣮ࡍʹฦͬͯ͘Δͷ͸UIDeviceRGBColor΍UIDeviceWhiteColor

    • ଞʹ΋Ӆ͠ػೳ͕͋ͬͨΒڭ͍͑ͯͩ͘͞

    • ͍ͯ͏͔ͳΜͰNSColor͕ཁΔΜͰ͠ΐ͏…ʁ
    44

    View Slide

  45. DataܕΛհͯ͠৭σʔλΛ෮ݩͰ͖ͪΌͬͨ
    Cocoa.NSColor→Data→UIColor
    let color = Cocoa.NSColor(calibratedWhite: 0.5, alpha: 0.5)

    let colorData = try! NSKeyedArchiver.archivedData(
    withRootObject: color, requiringSecureCoding: true
    )

    try! colorData.write(to: URL(fileURLWithPath: 略))
    let data = try! Data(contentsOf: URL(fileURLWithPath: 略))

    let color = try! NSKeyedUnarchiver.unarchivedObject(
    ofClasses: [UIColor.self], from: data
    ) // ここでUIKit.NSColor.init(coder:)が呼ばれる
    print(color) // Optional(UIExtendedGrayColorSpace 0.5 0.5)
    45

    View Slide

  46. UIColorͱαϒΫϥεͨͪʢ࠶ܝʣ
    46

    View Slide

  47. UIColorͷαϒΫϥεࣗ࡞͸
    ݁ߏ೉͍͠ɻ
    47

    View Slide

  48. UIColorͷαϒΫϥεΛࣗ࡞͢Δͱ͸
    48

    View Slide

  49. • ·ͣ͸αϒΫϥεΛ࡞Δ

    • ϓϩύςΟ΍ϝιουΛܧঝͯ͠ઐ༻ͷॲཧΛ࣮૷͓ͯ͘͠
    ྫ͑͹͜Μͳײ͡ (1/2)
    @implementation MyColor: UIColor
    - (instancetype _Nonnull)initWithMyProperty:略 {

    return self;
    }
    - (CGColorRef)CGColor { // 必要なプロパティやメソッドを継承
    return 略;
    }



    @end
    49

    View Slide

  50. • UIColorʹ࡞੒༻ͷΠχγϟϥΠβΛ࣋ͨͤΔ

    • privateͳαϒΫϥεͷΠϯελϯεΛ࡞੒͢ΔखஈΛ༻ҙ͢Δ
    ྫ͑͹͜Μͳײ͡ (2/2)
    @implementation UIColor(MyColor) // UIColorにイニシャライザを持たせる
    - (UIColor * _Nonnull)initWithMyProperty:略 {
    return [[MyColor alloc] initWithMyProperty:略];
    }
    @end
    50

    View Slide

  51. ޙ෇͚ͰαϒΫϥεΛ࡞੒͢Δ৔߹ͷ೉қ౓
    • UIColor௚Լʹ࡞Δɿ؆୯ͳ΋ͷͳΒOK

    • ܧঝΛ๨Εͨϝιου΍ϓϩύςΟ͕͋Δͱ࠷ѱΫϥογϡ͢ΔͷͰ஫ҙ

    • SwiftͰͷ࣮૷͸ແཧʢHAKATA.swiftͰͷൃදΛݟͯͶʣ

    • privateͳαϒΫϥεͷԼʹ͚ͭΔɿແཧ

    • खग़͠Ͱ͖ͳ͍

    • dynamic color΍pattern colorΛ࡞Δɿ࣮࣭ແཧ

    • ϓϩύςΟ͕privateͳͷͰ͍͡ΔͱౖΒΕͦ͏
    51

    View Slide

  52. dynamic colorΛ࡞Δ৔߹
    • ࢓ํ͕ͳ͍ͷͰUIColorΛ௚઀ܧঝ͢Δ

    • isDynamicΛਅʹͯ͠ɺtrait͕มԽͨ͠ͱ͖ʹ࠶ܭࢉͯ͠΋Β͏

    • ͪΌΜͱಈ͔͘͸஌Γ·ͤΜ
    - (BOOL)_isDynamic {
    return YES;
    }
    52

    View Slide

  53. ৄ͘͠͸
    • ୈ13ճHAKATA.swiftʮUIColor ClusterʯͷࢿྉΛݟͯͶ

    • σβΠϯύλʔϯ΍Swiftͷ࢓༷ʹॏ఺Λஔ͍ͯઆ໌͍ͯ͠·͢

    • @S_Shimotori_pub Ѽʹ࣭໰Λ౤͍͛ͯͩ͘͞
    53

    View Slide

  54. UIColorͷϝιουͷڍಈΛݟΔ
    54

    View Slide

  55. αϒΫϥεʹࢧ͑ΒΕͨϝιου&ϓϩύςΟ
    • withAlphaComponent(_:)

    • resolvedColor(with:)

    • cgColor, ciColor

    • set(), setFill(), setStroke()

    • getHue(ུ) / getRed(ུ) / getWhite(ུ)

    • isEqual(to:)
    ⚠αϒΫϥε͝ͱʹಈ࡞͕ҟͳΔ͔΋⚠
    55

    View Slide

  56. withAlphaComponent(_:)
    • UIPlaceholderColor͸ಛఆͷ৭Λࢦ͍ͯ͠ͳ͍ͷͰΫϥογϡ

    • static colorͰ͸୯७ʹalpha componentΛ্ॻ͖͢Ε͹OK

    • ݩͱಉ͡Ϋϥε͕໭Γ஋ͱͯ͠ฦ͞ΕΔ

    • alpha componentҎ֎͸มߋ͞Εͳ͍

    • dynamic color͸ղܾͷͨͼʹalpha componentΛ্ॻ͖͢Δඞཁ͕͋Δ

    • ͭ·ΓUIDynamicModifiedColor͕ཁΔ

    • ͜ͷϝιουΛ࣮ߦͯ͠΋ݩͷUIDynamicColor͸ҡ࣋͞ΕΔ
    56

    View Slide

  57. cgColorɺ resolvedColor(with:)
    ৭ͷղܾ
    • UIPlaceholderColor͸ಛఆͷ৭Λࢦ͍ͯ͠ͳ͍ͷͰΫϥογϡ

    • dynamic colorʹͱͬͯ͸ಛఆͷҰ৭ʹܾఆ͢Δૢ࡞

    • cgColor͸UITraitCollection.currentΛ࢖͍ͬͯΔΑ͏ʹݟ͑Δ

    • ྫ: layer.borderColor = dynamicColor.cgColor ͸࠷ॳ͚ͩਖ਼͍͠৭Ͱදࣔ͞ΕΔ

    • resolvedColor(with:)Ͱ͋Ε͹༩͑ͨUITraitCollectionͰ
    57

    View Slide

  58. isEqual(to:)
    • UIPlaceholderColor͸ಛఆͷ৭Λࢦ͍ͯ͠ͳ͍ͷͰΫϥογϡ

    • ಉ͡αϒΫϥεͰɺϓϩύςΟ͕౳஋ͳΒਅʁ

    • ྫɿUIColor.whiteͱUIColor(white: 1, alpha: 1)͸ਅ

    • ྫɿUIColor(red: 1, green: 1, blue: 1, alpha: 1)ͱUIColor(white: 1, alpha: 1)͸ِ

    • UICIColorͱUICGColorͱͷ൑ఆ͸ِʹͳΔ

    • UIDynamicProviderColor͸ಉҰੑ൑ఆ͕ਅͰͳ͚Ε͹౳஋൑ఆ΋ਅʹͳΒͳ͍

    • UIDynamicAppDefinedColorʹ͢Ε͹౳஋൑ఆ͕ਅʹͳΕΔ
    58

    View Slide

  59. ͪΐͬͱ໾ʹཱ͔ͭ΋͠Εͳ͍tips
    • XCTAssertEqualͰUIColorΛςετ͢Δͱ͖͸ɺಉ͡αϒΫϥεͰ൑ఆ͠Α͏

    • ҧ͏αϒΫϥεಉ࢜Ͱ͸equalʹͳΒͳ͍ͷͰςετ͕௨Βͳ͍
    ❌ UIDeviceRGBColorͷനͱUICachedDeviceWhiteColorͷന

    XCTAssertEqual(UIColor(red: 1, green: 1, blue: 1, alpha: 1), UIColor.white)

    ✅ UI(Cached)DeviceWhiteColorಉ࢜

    XCTAssertEqual(UIColor(white: 1, alpha: 1), UIColor.white)
    59

    View Slide

  60. ·ͱΊ
    60

    View Slide

  61. UIColorͱ͸
    • ৭ͷ༷ʑͳࢦఆํ๏Λαϙʔτ͢ΔͨΊɺࢥͬͨҎ্ʹෳࡶ

    • ෳࡶͳͭ͘ΓΛ͍ͯ͠Δ͚ͩͷཧ༝͕͋Δ

    • ࢲͨͪ͸UIColor͑͞஌͍ͬͯΕ͹OK
    • ࡉ͔͍͜ͱ͕ؾʹͳͬͨΒࢥ͍ग़͍ͯͩ͘͠͞
    61

    View Slide

  62. ࢀߟจݙͳͲ
    62

    View Slide

  63. ࢀߟจݙͱ͔໘നͦ͏ͳϖʔδͱ͔
    • Randomizing UIColor with Method Swizzling | Jonathan Cole

    • ʲIOS ARCʳ UIColor͕ϝϞϦʹ࢒͍ͬͯΔΑ͏ͳؾ͕͢Δ – ඥ෇͚ͳ೔ʑ

    • Patterns

    • Core Graphics Tutorial: Patterns | raywenderlich.com

    • iOS ൌགྷapp∍ന໛ࣜ - ࡥ඀

    • nygard/class-dump: Generate Objective-C headers from Mach-O files.

    • nst/RuntimeBrowser: Objective-C Runtime Browser, for Mac OS X and iOS
    63

    View Slide

  64. ૉࡐ
    • ͔Θ͍͍ϑϦʔૉࡐू ͍Β͢ͱ΍

    • ;͖ͩ͠ૉࡐઐ໳αΠτʮϑΩμγσβΠϯʯ – Just another WordPress site
    64

    View Slide