Share
Embed
UIColor Cluster
第13回 HAKATA.swift「UIColor Cluster」の発表資料です。
https://hakata-swift.connpass.com/event/176661/
#hakataswift
Shigure Shimotori
June 19, 2020
Transcript
41 slides
-
S_Shimotori • Twitter: @S_Shimotori_pub • ண৭৬ਓ • Dark ModeରԠͨ͠ •
Objective CϚδͰΘ͔Βͳ͍ • ݟಀͯ͠΄͍͠ -
class UIColor • UIKitఏڙͷɺ৭σʔλΛ֨ೲͨ͠ΦϒδΣΫτ • ͨ͘͞ΜΠχγϟϥΠβ͕͋Δ • ϝιουͦΜͳʹͳ͍ • Dark
ModeରԠͰΊͬͪΌ͓ੈʹͳͬͨɹݟ͖ͨʂ -
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 → -
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 -
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 → -
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__: …>> -
UIColor૾ਤ UIColor UIDynamicProviderColor UIDynamicSystemColor UI??????????Color • init(white:alpha:) • init(red:green:blue:alpha) •
systemBackground • label • init(dynamicProvider:) ※ਖ਼֬Ͱͳ͍ var description: StringͳͲ֤ࣗઃఆ͢Δʂ -
Class Clusterͬͯͳʹ • Foundation framework͕ଟ༻͢ΔσβΠϯύλʔϯɺΒ͍͠ • Abstract FactoryσβΠϯύλʔϯͷੜ • ෳͷprivateͳsub
classΛɺநత͕ͩpublicͳsuper classͷԼʹஔ • ػೳͷॆ࣮۩߹ͦͷ··ʹɺpublicʹͳ͍ͬͯΔॴ͚ͩʹूதͰ͖Δ • super classɺsub classͷΠϯελϯεΛ࡞͢ΔϝιουΛ࣋ͭ -
Class ClusterͷྫʁɿNSNumber NSNumber long long int long int char short
int int float double NSNumberɺ֤sub classͷΦϒδΣΫτΛ࡞͢ΔͨΊͷϝιουΛ࣋ͭʁ • numberWithChar: • numberWithInt: • ͳͲͳͲʁ -
ΦʔϓϯιʔεNSNumberʁ • ཪCFNumber • “An object wrapper for primitive scalar
numeric values.” • CFNumberCreateͰ୯७ʹbitͱछผΛهԱ͍ͯ͠Δ͚ͩͬΆ͍ʁ • Class ClusterͰͳͦ͞͏…… -
ΦʔϓϯιʔεNSArrayʁ • internal var _storage = [AnyObject]() • open class
NSMutableArray : NSArray • ͬͺΓClass ClusterͰͳͦ͞͏…… -
UIColor͕Γͳ͍ͱࢥͬͨΒ • Ҋ1ɿ͍ͭ௨ΓUIColorΛܧঝ͢Δ • Ҋ2ɿUIColorΛϥοϓ͢ΔclassΛ࡞ͬͯޡຐԽ͢ • private var innerColor: UIColor
ͳײ͡ͰͲ͏Ͱ͠ΐ͏ • Ҋ3ɿextensionͰϝιουΛੜ͢ -
UIColorΛܧঝͯ͠ΈΔ • Class ClusterΛܧঝ͢Δͱ͖ͷҙΛकΔʂʂ • super classΛܧঝͯ͠࡞Δ͜ͱ • ඞཁͳϓϩύςΟΛએݴ͢Δ͜ͱ •
શͯͷΠχγϟϥΠβΛΦʔόʔϥΠυ͢Δ͜ͱ • શͯͷprimitive methodΛΦʔόʔϥΠυ͢Δ͜ͱ • UIColorΛܧঝ͢Δͱ͖ͷҙΛकΔʂʂ • Ճ͢ΔϝιουϓϩύςΟɺεϨουηʔϑͰͳ͚ΕͳΒͳ͍ -
UIColorʹඞཁͳύϥϝʔλΛ͢ • UIColorࣗମʹɺ৭ۭؒίϯϙʔωϯτΛهԱͤ͞Δखஈ͕ͳ͍ • 1൪؆୯ͳͷinit(cgColor:)ͰCGColorΛͯ͠͠·͏Γํ • CGColorͷΠχγϟϥΠβͳΒ৭ۭؒΛࢦఆՄೳ ↓Πϝʔδ͜Μͳײ͡↓ init(myWhite: CGFloat,
alpha: CGFloat) { super.init(cgColor: CGColor( colorSpace: // ここに色空間 components: // ここにコンポーネント値 ))! } -
ΠχγϟϥΠβʹ৮Εͳ͍ • 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ͳΒͳΜͱ͔ɻ -
ิɿmethod dispatch • ͲͷϝιουΛݺͼग़͔͢Λܾఆ͢ΔΈͷ͜ͱ • static dispatchʢίϯύΠϧ࣌ʹܾఆʣ • structenumfinalͱ͍ͬͨΦʔόʔϥΠυෆՄͳͷ͕ͬͪ͜ •
extensionͰՃͨ͠ϝιουͬͪ͜ • dynamic dispatchʢίϯύΠϧ࣌ʹtable࡞ɺ࣮ߦ࣌ʹܾఆʣ • ΦʔόʔϥΠυՄೳͳͷͬͪ͜ • extensionͰޙ͚ͨ͠ϝιουtableʹೖΕͯΒ͑ͳ͍ આ໌ؒҧͬͯͨΒ͝ΊΜͳ͍͞ʂ -
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) } } -
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) -
SwiftͰ࣮ߦͯ͠Έͨ • white = 0.0, 0.1, …, 0.9, 1.0ͷ৭Λฒͨ •
ࠨྻɿΨϯϚ2.2ʢ͍ͭͷʣ • ӈྻɿΨϯϚ1.5ʢMyCustomColorʣ White: 0.0 → White: 1.0 → White: 0.5→ -
৽͍͠ϞσϧͬͯͭΛ࡞Γ͍ͨ • ಈతʹ৭Λܾఆ͢Δɺશ͘৽͍͠ϞσϧͷUIColorΛ࡞Δͧʂ • UIDynamicProviderColorͱಉ͡ͷΛ࡞Δ͜ͱʹઓ • init(myDynamicProvider:)ͳײ͡Ͱ • ࠓճObjCͰؤுΔʢมͳॻ͖ํͯͨ͠ΒεϛϚηϯʣ ↓Πϝʔδ͜Μͳײ͡↓
self = [super init]; if (self) { _myDynamicProvider = myDynamicProvider; } return self; -
ຊདྷඞਢͳใΛൈ͖ʹ࡞͍ͬͯ͘ • طଘΠχγϟϥΠβ৭ۭؒ&ίϯϙʔωϯτΛͣ͞ʹܧঝ͢ΔͳΒɺ UIColorͷϓϩύςΟϝιουΛશͯਖ਼͘͠ΦʔόʔϥΠυ͢Δඞཁ͕͋Δ • ઌ΄Ͳͷ[super init]͚ͩͰΫϥογϡͷݪҼʹͳΔ • UIColorͷϝιου͚ͩͰͳ͘isEqual:ͷΦʔόʔϥΠυΕͣʹ •
৭ͷఆॲཧ͜ΕΒͷใʹґଘ͍ͯ͠ΔͨΊ *** -CGColor not defined for the UIColor <ུ>; need to first convert colorspace. -
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 -
Objective CͰ࣮ͯ͠Έͨ(2/3) Ұ෦ @implementation UIColor(MyColor) + (UIColor * _Nonnull)initWithMyDynamicProvider:(UIColor *
_Nonnull (^ _Nonnull)(UITraitCollection * _Nonnull traitCollection))myDynamicProvider { return [[MyDynamicColor alloc] initWithMyDynamicProvider:myDynamicProvider]; } @end -
Θ͔ͬͨ͜ͱ • FoundationUIKitʹɺClass Clusterͱ͍͏σβΠϯύλʔϯʹଇͬͨΫϥε ͕ଘࡏ͍ͯ͠Δʢ͔͠Εͳ͍) • Swiftʹԑ͕ͳ͍ͷ͔ɻɻ • Ͳ͏ͯ͠sub classΛ࡞Βͳ͚Ε͍͚ͳ͍࣌৻ॏʹ
• UIColorͷsub classΛ࡞Δͷେม • SwiftͰΔͷ͞Βʹແཧ͕͋Δ • ৭ۭؒͷઃఆΛ͍͡Δ͘Β͍͕ݶʁ • Ί͓͍ͯͨ΄͏͕͍͍ͱࢥ͍·͢ -
ࢀߟจݙͱ͔ • 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