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

UIColor Cluster

UIColor Cluster

第13回 HAKATA.swift「UIColor Cluster」の発表資料です。
https://hakata-swift.connpass.com/event/176661/

#hakataswift

Shigure Shimotori

June 19, 2020
Tweet

More Decks by Shigure Shimotori

Other Decks in Programming

Transcript

  1. var description: String UIColor(white: 1, alpha: 1).description → UIColor(red: 1,

    green: 1, blue: 1, alpha: 1).description → UIColor(dynamicProvider: { _ in return .white }).description →
  2. var description: String UIColor(white: 1, alpha: 1).description → UIExtendedGrayColorSpace 1

    1 UIColor(red: 1, green: 1, blue: 1, alpha: 1).description → UIColor(dynamicProvider: { _ in return .white }).description → ↓xcassetsͰͷExtended Gray
  3. var description: String UIColor(white: 1, alpha: 1).description → UIExtendedGrayColorSpace 1

    1 UIColor(red: 1, green: 1, blue: 1, alpha: 1).description → UIExtendedSRGBColorSpace 1 1 1 1 UIColor(dynamicProvider: { _ in return .white }).description →
  4. var description: String UIColor(white: 1, alpha: 1).description → UIExtendedGrayColorSpace 1

    1 UIColor(red: 1, green: 1, blue: 1, alpha: 1).description → UIExtendedSRGBColorSpace 1 1 1 1 UIColor(dynamicProvider: { _ in return .white }).description → <UIDynamicProviderColor: …; provider = <__NSMallocBlock__: …>>
  5. UIColor૝૾ਤ UIColor UIDynamicProviderColor UIDynamicSystemColor UI??????????Color • init(white:alpha:) • init(red:green:blue:alpha) •

    systemBackground • label • init(dynamicProvider:) ※ਖ਼֬Ͱ͸ͳ͍ var description: StringͳͲ͸֤ࣗઃఆ͢Δʂ
  6. Class Clusterͬͯͳʹ • Foundation framework͕ଟ༻͢ΔσβΠϯύλʔϯɺΒ͍͠ • Abstract FactoryσβΠϯύλʔϯͷ೿ੜ • ෳ਺ͷprivateͳsub

    classΛɺந৅త͕ͩpublicͳsuper classͷԼʹ഑ஔ • ػೳͷॆ࣮۩߹͸ͦͷ··ʹɺpublicʹͳ͍ͬͯΔॴ͚ͩʹूதͰ͖Δ • super class͸ɺsub classͷΠϯελϯεΛ࡞੒͢ΔϝιουΛ࣋ͭ
  7. Class ClusterͷྫʁɿNSNumber NSNumber long long int long int char short

    int int float double NSNumber͸ɺ֤sub classͷΦϒδΣΫτΛ࡞੒͢ΔͨΊͷϝιουΛ࣋ͭʁ • numberWithChar: • numberWithInt: • ͳͲͳͲʁ
  8. ΦʔϓϯιʔεNSNumber͸ʁ • ཪ͸CFNumber • “An object wrapper for primitive scalar

    numeric values.” • CFNumberCreateͰ୯७ʹbitͱछผΛهԱ͍ͯ͠Δ͚ͩͬΆ͍ʁ • Class ClusterͰ͸ͳͦ͞͏……
  9. ΦʔϓϯιʔεNSArray͸ʁ • internal var _storage = [AnyObject]() • open class

    NSMutableArray : NSArray • ΍ͬͺΓClass ClusterͰ͸ͳͦ͞͏……
  10. UIColorΛܧঝͯ͠ΈΔ • Class ClusterΛܧঝ͢Δͱ͖ͷ஫ҙ఺ΛकΔʂʂ • super classΛܧঝͯ͠࡞Δ͜ͱ • ඞཁͳϓϩύςΟΛએݴ͢Δ͜ͱ •

    શͯͷΠχγϟϥΠβΛΦʔόʔϥΠυ͢Δ͜ͱ • શͯͷprimitive methodΛΦʔόʔϥΠυ͢Δ͜ͱ • UIColorΛܧঝ͢Δͱ͖ͷ஫ҙ఺ΛकΔʂʂ • ௥Ճ͢Δϝιου΍ϓϩύςΟ͸ɺεϨουηʔϑͰͳ͚Ε͹ͳΒͳ͍
  11. ΠχγϟϥΠβʹ৮Εͳ͍໰୊ • UIColorͷrequired initΛΦʔόʔϥΠυ͠ͳ͚Ε͹ͳΒͳ͍ • UIColorͷrequired initΛΦʔόʔϥΠυͰ͖ͳ͍ʢmethod dispatchͷ౎߹ʣ Overriding non-@objc

    declarations from extensions is not supported @nonobjc required convenience init( _colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float ) Objective CͳΒͳΜͱ͔ɻ
  12. ิ଍ɿmethod dispatch • ͲͷϝιουΛݺͼग़͔͢Λܾఆ͢Δ࢓૊Έͷ͜ͱ • static dispatchʢίϯύΠϧ࣌ʹܾఆʣ • struct΍enum΍finalͱ͍ͬͨΦʔόʔϥΠυෆՄͳ΋ͷ͕ͬͪ͜ •

    extensionͰ௥Ճͨ͠ϝιου΋ͬͪ͜ • dynamic dispatchʢίϯύΠϧ࣌ʹtable࡞੒ɺ࣮ߦ࣌ʹܾఆʣ • ΦʔόʔϥΠυՄೳͳ΋ͷ͸ͬͪ͜ • extensionͰޙ෇͚ͨ͠ϝιου͸tableʹೖΕͯ΋Β͑ͳ͍ આ໌ؒҧͬͯͨΒ͝ΊΜͳ͍͞ʂ
  13. SwiftͰ࣮૷ͯ͠Έͨ(1/2) private class MyCustomColor: UIColor {
 private static let whitePoint:

    [CGFloat] = [76.04, 80, 87.12]
 private static let blackPoint: [CGFloat] = [0.1901, 0.2, 0.2178] static func create(
 gamma1_5Gray gray: CGFloat, alpha: CGFloat
 ) -> MyCustomColor { // 色空間を新しく定義
 let colorSpace = CGColorSpace(
 calibratedGrayWhitePoint: whitePoint,
 blackPoint: blackPoint,
 gamma: 1.5 // ←この値をカスタムしてみた
 )!
 // 色空間とコンポーネント値を設定
 let cgColor = CGColor(
 colorSpace: colorSpace,
 components: [gamma1_5Gray, alpha]
 )!
 // initしたつもり……
 return MyCustomColor(cgColor: cgColor) }
 }
  14. SwiftͰ࣮૷ͯ͠Έͨ(2/2) extension UIColor {
 // publicなイニシャライザのつもり
 static func create(
 gamma1_5Gray

    gray: CGFloat, alpha: CGFloat
 ) -> UIColor {
 return MyCustomColor.create(gamma1_5Gray: gray, alpha: alpha)
 }
 } // ガンマ値2.2のいつもの白
 let gamma2_2Color = UIColor(white: 1, alpha: 1)
 // ガンマ値1.5の白
 let gamma1_5Color = UIColor.create(gamma1_5Gray: 1, alpha: 1)
  15. SwiftͰ࣮ߦͯ͠Έͨ • white = 0.0, 0.1, …, 0.9, 1.0ͷ৭Λฒ΂ͨ •

    ࠨྻɿΨϯϚ2.2ʢ͍ͭ΋ͷʣ • ӈྻɿΨϯϚ1.5ʢMyCustomColorʣ White: 0.0 → White: 1.0 → White: 0.5→
  16. Objective CͰ࣮૷ͯ͠Έͨ(1/3) Ұ෦ൈਮ @implementation MyDynamicColor: UIColor - (instancetype _Nonnull)initWithMyDynamicProvider:(UIColor *

    _Nonnull (^ _Nonnull)(UITraitCollection * _Nonnull traitCollection))myDynamicProvider {
 self = [super init];
 if (self) {
 _myDynamicProvider = myDynamicProvider;
 }
 return self;
 } - (CGColorRef)CGColor {
 return _myDynamicProvider(UITraitCollection.currentTraitCollection).CGColor;
 } // その他のメソッドもオーバーライド @end
  17. Objective CͰ࣮૷ͯ͠Έͨ(2/3) Ұ෦ @implementation UIColor(MyColor) + (UIColor * _Nonnull)initWithMyDynamicProvider:(UIColor *

    _Nonnull (^ _Nonnull)(UITraitCollection * _Nonnull traitCollection))myDynamicProvider { return [[MyDynamicColor alloc] initWithMyDynamicProvider:myDynamicProvider]; } @end
  18. Θ͔ͬͨ͜ͱ • Foundation΍UIKitʹ͸ɺClass Clusterͱ͍͏σβΠϯύλʔϯʹଇͬͨΫϥε ͕ଘࡏ͍ͯ͠Δʢ͔΋͠Εͳ͍) • Swiftʹ͸ԑ͕ͳ͍΋ͷ͔΋ɻɻ • Ͳ͏ͯ͠΋sub classΛ࡞Βͳ͚Ε͹͍͚ͳ͍࣌͸৻ॏʹ

    • UIColorͷsub classΛ࡞Δͷ͸େม • SwiftͰ΍Δͷ͸͞Βʹແཧ͕͋Δ • ৭ۭؒͷઃఆ஋Λ͍͡Δ͘Β͍͕ݶ౓ʁ • ΍Ί͓͍ͯͨ΄͏͕͍͍ͱࢥ͍·͢
  19. ࢀߟจݙͱ͔ • https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/ ClassClusters/ClassClusters.html • https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/ ClassCluster.html • https://developer.apple.com/documentation/uikit/uicolor •

    http://www.color.org/sRGB.pdf • https://github.com/apple/swift-corelibs-foundation/blob/cfac32b92d5fb62a651967cf22756352179b58ba/ CoreFoundation/NumberDate.subproj/CFNumber.c • https://qiita.com/HaNoHito/items/f40bfc1717c1e922a5b0 • https://stackoverflow.com/questions/55364212/overriding-non-objc-declarations-from-extensions-is-not- supported • https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001922.html • https://github.com/xybp888/iOS-Header/blob/master/13.0/PrivateFrameworks/UIKitCore.framework/UIColor.h