国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

swift NightNight夜間模式設(shè)計(jì)分析

這篇具有很好參考價(jià)值的文章主要介紹了swift NightNight夜間模式設(shè)計(jì)分析。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

設(shè)計(jì)目標(biāo)

與objective-c的DKNightMode相同,對(duì)于當(dāng)前控件實(shí)現(xiàn)背景色,字體顏色等在不同模式下的顏色設(shè)置和變更,同時(shí)提供模式變更的閉包調(diào)用

實(shí)現(xiàn)原理

基礎(chǔ)設(shè)計(jì)

NSObject的擴(kuò)展

動(dòng)態(tài)屬性notificaitonManager
  • 該設(shè)計(jì)主要的目的是實(shí)現(xiàn)隱式的NSNotificationCenter的注冊(cè)和去注冊(cè),通過observer weak持有self,避免循環(huán)引用;利用selectorToBoolMap確保selector的有效性;析構(gòu)時(shí)隱式確保self從notificationCenter中移除
  • 通過addNightObserver,實(shí)現(xiàn)NSNotificaitonCenter的注冊(cè)和selector有效性性檢查.
  • NightNightThemeChangeNotification是每次theme發(fā)生變化時(shí)的notificaiton通知邏輯
private class NotificationManager {
    var selectorToBoolMap: [Selector: Bool] = [:]
    weak var observer: NSObject?

    init(observer: NSObject) {
        self.observer = observer
    }

    deinit {
        if let observer = observer {
            NotificationCenter.default.removeObserver(observer)
        }
    }

}

extension NSObject {
    fileprivate var notificationManager: NotificationManager {
        get {
            if let manager = objc_getAssociatedObject(self, &notificationManagerKey) as? NotificationManager {
                return manager
            }
            self.notificationManager = NotificationManager(observer: self)
            return self.notificationManager
        }
        set {
            objc_setAssociatedObject(self, &notificationManagerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    func addNightObserver(_ selector: Selector) {
        if let bool = notificationManager.selectorToBoolMap[selector] {
            if bool {
                return
            }
        } else {
            notificationManager.selectorToBoolMap[selector] = true
        }
        NotificationCenter.default.addObserver(self, selector: selector, name: NSNotification.Name(rawValue: NightNightThemeChangeNotification), object: nil)

    }

}

動(dòng)態(tài)屬性key對(duì)應(yīng)的顏色值
    func getMixedColor(_ key: UnsafeRawPointer) -> MixedColor? {
        return objc_getAssociatedObject(self, key) as? MixedColor
    }
    func setMixedColor(_ key: UnsafeRawPointer, value: MixedColor?) {
        objc_setAssociatedObject(self, key, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)

        addNightObserver(#selector(_updateTheme))
    }

動(dòng)態(tài)屬性key對(duì)應(yīng)的顏色值保存,在設(shè)置時(shí)注冊(cè)notificationManager及對(duì)應(yīng)的updateTheme函數(shù)的調(diào)用。

updateTheme和_updateCurrentStatus

實(shí)現(xiàn)updateTheme是所有NSObject對(duì)應(yīng)的響應(yīng)通知的入口,而_updateCurrentStatus則是各種不同控件在響應(yīng)時(shí)的獨(dú)立行為,所有需要響應(yīng)的控件都有必要實(shí)現(xiàn)該方法的繼承。例如:

public extension UITableView {
    override func _updateCurrentStatus() {
        super._updateCurrentStatus()
        
        if let mixedSeparatorColor = mixedSeparatorColor {
            separatorColor = mixedSeparatorColor.unfold()
        }
        
        if let mixedSectionIndexBackgroundColor = mixedSectionIndexBackgroundColor {
            sectionIndexBackgroundColor = mixedSectionIndexBackgroundColor.unfold()
        }
        
    }
}

public extension UIView {
    override func _updateCurrentStatus() {
        super._updateCurrentStatus()
        
        if let mixedBackgroundColor = mixedBackgroundColor {
            backgroundColor = mixedBackgroundColor.unfold()
        }
        
        if let mixedTintColor = mixedTintColor {
            tintColor = mixedTintColor.unfold()
        }
        
    }
}

動(dòng)態(tài)閉包Customize

該設(shè)計(jì)主要是提供在模式轉(zhuǎn)換下的閉包調(diào)用,在這個(gè)層面上不知道為何作者并沒有開放成public方法,所以私下里我對(duì)這個(gè)邏輯進(jìn)行重新整理

open class Customize: NSObject {
    fileprivate var closures: [(NightNight.Theme) -> ()] = []
    fileprivate weak var correspondingObject: NSObject?

    fileprivate convenience init(obj: NSObject) {
        self.init()
        self.correspondingObject = obj

        NotificationCenter.default.addObserver(self, selector: #selector(_callAllExistingClosures), name: NSNotification.Name(rawValue: NightNightThemeChangeNotification), object: nil)
    }

    @objc func _callAllExistingClosures() {
        closures.forEach {
            $0(NightNight.theme)
        }
    }
}

通過擴(kuò)展屬性customiz,向所有空間提供模式變更下的閉包調(diào)用。

各類型控件的顏色擴(kuò)展

添加關(guān)聯(lián)的屬性字,實(shí)現(xiàn)多模式下顏色值的保存,實(shí)現(xiàn)_updateCurrentState方法

public extension UIView {
    
    var mixedBackgroundColor: MixedColor? {
        get { return getMixedColor(&Keys.backgroundColor) }
        set {
            backgroundColor = newValue?.unfold()
            setMixedColor(&Keys.backgroundColor, value: newValue)
        }
    }
    
    var mixedTintColor: MixedColor? {
        get { return getMixedColor(&Keys.tintColor) }
        set {
            tintColor = newValue?.unfold()
            setMixedColor(&Keys.tintColor, value: newValue)
        }
    }
    

    override func _updateCurrentStatus() {
        super._updateCurrentStatus()
        
        if let mixedBackgroundColor = mixedBackgroundColor {
            backgroundColor = mixedBackgroundColor.unfold()
        }
        
        if let mixedTintColor = mixedTintColor {
            tintColor = mixedTintColor.unfold()
        }
        
    }
}

模式切換的各資源類型

  • 利用模板實(shí)現(xiàn)有關(guān)模式切換的類型
public class MixedResource<T> {
    public let normalResource: T
    public let nightResource: T
    public init(normal: T, night: T) {
        normalResource = normal
        nightResource = night
    }

    public func unfold() -> T {
        switch NightNight.theme {
        case .normal: return normalResource
        case .night:  return nightResource
        }
    }
}

  • UIColor,UIImage, UIStatusBarStyle,UIBarStyle,UIKeyboardAppearance
public class MixedImage: MixedResource<UIImage> {
    public override init(normal: UIImage, night: UIImage) {
        super.init(normal: normal, night: night)
    }
    public convenience init(normal: String, night: String) {
        self.init(normal: UIImage(named: normal)!, night: UIImage(named: night)!)
    }
}

public class MixedColor: MixedResource<UIColor> {
    public override init(normal: UIColor, night: UIColor) {
        super.init(normal: normal, night: night)
    }
    public init(normal: Int, night: Int) {
        let normalColor = UIColor(rgb: normal)
        let nightColor = UIColor(rgb: night)
        super.init(normal: normalColor, night: nightColor)
    }
}

該設(shè)計(jì)提供更多彈性增加可在模式變更下切換的資源類

GitHub地址

github地址文章來源地址http://www.zghlxwxcb.cn/news/detail-796974.html

到了這里,關(guān)于swift NightNight夜間模式設(shè)計(jì)分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • iOS開發(fā)Swift-函數(shù)

    ?(1)無參函數(shù) (2)多參函數(shù) (3)無返回值 (4)多重返回值 (5)可選元組返回類型(元組可以是nil) (6)隱式返回的函數(shù) 任一可以被寫成一行return的函數(shù),return(x) + for。 調(diào)用的時(shí)候: 方法名(for: 參數(shù)) (1)指定參數(shù)標(biāo)簽 (2)忽略參數(shù)標(biāo)簽 (3)默認(rèn)參數(shù)值 (4)可變參數(shù) 一個(gè)可變參數(shù)可接受0個(gè)或多

    2024年02月11日
    瀏覽(27)
  • iOS開發(fā)Swift-閉包

    將很長(zhǎng)的閉包表達(dá)式作為最后一個(gè)參數(shù)傳遞給函數(shù),不用寫出他的參數(shù)標(biāo)簽。 嵌套函數(shù)可捕獲其外部函數(shù)所有參數(shù)、變量、常量。 當(dāng)一個(gè)閉包作為一個(gè)參數(shù)傳到一個(gè)函數(shù)中,但閉包在函數(shù)返回之后才被執(zhí)行,則稱閉包逃逸。 標(biāo)注@escaping,表示允許閉包逃逸。 ?包裝傳遞給函數(shù)

    2024年02月11日
    瀏覽(17)
  • iOS開發(fā)Swift-枚舉

    枚舉:一組相關(guān)的值定義了一個(gè)共同的類型,使你可以在代碼中以類型安全的方式來使用這些值。 原始值:定義枚舉時(shí)被預(yù)先填充的值。 (1)整數(shù)為原始值時(shí),隱式賦值遞增1。未設(shè)置原始值時(shí),默認(rèn)為0,之后遞增1. (2)字符串為原始值,隱式賦值為枚舉成員的名稱。

    2024年02月11日
    瀏覽(28)
  • iOS開發(fā)Swift-基礎(chǔ)部分

    系統(tǒng)可通過賦初始值進(jìn)行自動(dòng)推斷。 平時(shí)可加可不加,同一行中有兩句話必須加。 Int?????????? UInt(最好不用) Double 64位 很大/高精度情況下使用 15位小數(shù) Float 32位 對(duì)精度要求不高的情況下用 6位小數(shù) 十進(jìn)制數(shù) ? 17 二進(jìn)制 0b前綴 0b10001 八進(jìn)制 0o前綴 0o21 十六進(jìn)制 0x前綴

    2024年02月11日
    瀏覽(23)
  • iOS開發(fā)Swift-控制流

    (1)復(fù)合匹配 (2)區(qū)間匹配 (3)元組匹配 (4)值綁定匹配 (5)where continue, break, fallthrough, return, throw continue: 停止本次循環(huán),開始下次循環(huán) break: 立即結(jié)束整個(gè)控制流??梢允褂胋reak忽略switch的分支。 fallthrough貫穿: switch中的case加入貫穿,case會(huì)穿透到下一個(gè)case/ default。

    2024年02月11日
    瀏覽(22)
  • iOS開發(fā)Swift-類型轉(zhuǎn)換

    1.Int或Double轉(zhuǎn)字符串 2.Double轉(zhuǎn)Int(去掉小數(shù)點(diǎn)后面的) 3.Int轉(zhuǎn)Double 4.向上轉(zhuǎn)型 5.向下轉(zhuǎn)型

    2024年02月09日
    瀏覽(21)
  • iOS開發(fā)Swift-集合類型

    集合基本類型:數(shù)組 Array (有序), 集合 Set (無序不重復(fù)), 字典 Dictionary (無序鍵值對(duì)) (1)數(shù)組的表示 (2)創(chuàng)建空數(shù)組 (3)帶值數(shù)組 (4)兩數(shù)組相加創(chuàng)建數(shù)組 (5)字面量創(chuàng)造數(shù)組 (6)訪問數(shù)組 (7)添加 (8)修改 (9)刪除 (10)遍歷 同時(shí)需要索引和值時(shí): (1)集合的表示 (2)構(gòu)造一個(gè)集合 (3)字面

    2024年02月11日
    瀏覽(27)
  • iOS開發(fā)Swift-基本運(yùn)算符

    一元 單一操作對(duì)象 -a??? !b??? c! 二元 兩個(gè)操作對(duì)象 2 + 3 三元 三目運(yùn)算符 a ? b : c 賦值運(yùn)算符不返回任何值,所以 if x = y { ... } 無效。 +?? - ? *?? / 默認(rèn)不允許數(shù)值運(yùn)算中溢出。 溢出運(yùn)算符:?? a + b a % b = 余數(shù) a = (b * 倍數(shù)) + 余數(shù) 所以a % b = a % -b ==???? !=????? ???

    2024年02月11日
    瀏覽(27)
  • iOS開發(fā)Swift-1-Xcode創(chuàng)建項(xiàng)目

    iOS開發(fā)Swift-1-Xcode創(chuàng)建項(xiàng)目

    1.創(chuàng)建項(xiàng)目 雙擊Xcode App,選擇Create a new Xcode project。 ?選擇創(chuàng)建一個(gè)iOS普通的App項(xiàng)目。選擇Single View App,點(diǎn)擊Next。 ?填寫項(xiàng)目名,組織名稱等,點(diǎn)擊next。 ?選擇好文件的存儲(chǔ)路徑,點(diǎn)擊create。 ?2.為前端添加組件 點(diǎn)擊Main,選中View,在右下角show the Object library中找到label組件,

    2024年02月10日
    瀏覽(24)
  • iOS開發(fā)Swift-字符串與字符

    ?前一個(gè)\\\"\\\"\\\"前和后一個(gè)\\\"\\\"\\\"后無換行 ?想要實(shí)現(xiàn)在代碼編寫時(shí)換行而在實(shí)際運(yùn)行后不換行:? (1)轉(zhuǎn)義字符 \\0 空字符 \\\\ 反斜線 t 水平制表符 n 換行符 r 回車符 \\\" 雙引號(hào) \\\' 單引號(hào) 要在\\\"\\\"\\\"中使用(\\\"\\\"\\\")時(shí),必須至少寫一個(gè)轉(zhuǎn)義符。例如 \\\"\\\"\\\" 或 \\\"\\\"\\\" (2)Unicode標(biāo)量 u{24} 兩位十六進(jìn)制

    2024年02月11日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包