Home-made product. The light-weight darkness in Swift you can force.
1:Build option kindaNight/Day/System ModeorOn/Off/System Dark Mode.
2:Be awared of Dark Mode changes if you need.
PDMis a single author and personale solution developed inP2Prelationship paradigm.
PDMSupportingStar.swiftis a peace of code a widly helpful in accord with PDM.
PDMSupportingStar.swiftgoes as an external part of PDM.
CPLstands forConsolePerseusLogger.
PGKstands forPerseusGeoKit.
PDMstands forPerseusDarkMode.
P2Pstands forPerson-to-Person.
A3stands forAppleAppsApprobation.
T3stands forTheTechnologicalTree.
In approbation:iOS appmacOS app
In business:The Dark Moon
For details:Approbation and A3 Environment/CHANGELOG
- In brief
- Build requirements
- First-party software
- Third-party software
- Installation
- Usage
- Points taken into account
- License MIT
- Credits
- Author
THE DARKNESS YOU CAN FORCE
| iOS window | iOS Settings bundle | macOS window |
|---|---|---|
![]() |
![]()
|
![]() |
But as the single source code file PDMStar.swift PDM can be used even in Xcode 10.1.
| Type | Name | License |
|---|---|---|
| Star | ConsolePerseusLogger / 1.6.0 | MIT |
| Type | Name | License |
|---|---|---|
| Style | SwiftLint / v0.57.0 for Monterey+ | MIT |
| Script | SwiftLint Shell Script to run SwiftLint | MIT |
| Action | mxcl/xcodebuild@v3 | Unlicense |
| Action | cirruslabs/swiftlint-action@v1 | MIT |
Step 1: Import the Darkness either with SPM or standalone
Standalone: the single source code file PDMStar.swift
Swift Package Manager:
https://github.com/perseusrealdeal/PerseusDarkMode
Step 2: In the AppDelegate when applicationDidFinishLaunching call force
import Cocoa
import PerseusDarkMode
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
DarkModeAgent.force(DarkModeUserChoice)
}
}Step 3: Register the MainWindowController for Dark Mode changes
import Cocoa
import PerseusDarkMode
class MainWindowController: NSWindowController, NSWindowDelegate {
override func windowDidLoad() {
super.windowDidLoad()
DarkModeAgent.register(stakeholder: self, selector: #selector(makeUp))
}
@objc private func makeUp() {
// Runs every time if Dark Mode changes.
// The current DarkMode value is reliable here.
let isDark = DarkMode.style == .dark
let _ = isDark ? "It's dark" : "No dark"
}
}Step 2: In the AppDelegate when didFinishLaunchingWithOptions call force
import UIKit
import PerseusDarkMode
class AppDelegate: UIResponder { var window: UIWindow? }
extension AppDelegate: UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Register Settings Bundle
registerSettingsBundle()
// Init the app's window
window = UIWindow(frame: UIScreen.main.bounds)
// Give it a root view for the first screen
window!.rootViewController = MainViewController.storyboardInstance()
window!.makeKeyAndVisible()
DarkModeAgent.force(DarkModeUserChoice)
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Actualize Dark Mode style to Settings Bundle
if let choice = DarkModeAgent.isDarkModeSettingsKeyChanged() {
DarkModeAgent.force(choice)
}
}
}Step 3: Register the MainViewController and process traitCollectionDidChange for DarkMode changes
import UIKit
import PerseusDarkMode
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
DarkModeAgent.register(stakeholder: self, selector: #selector(makeUp))
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 13.0, *) {
DarkModeAgent.processTraitCollectionDidChange(previousTraitCollection)
}
}
@objc private func makeUp() {
// Runs every time if Dark Mode changes.
// The current DarkMode value is reliable here, DarkModeAgent selector registered.
let isDark = DarkMode.style == .dark
let _ = isDark ? "It's dark" : "No dark"
}
}The Dark Mode of your app can be easely forced in
.on,.offor.autojust call methodforceof DarkModeAgent like this.
DarkModeAgent.force(.off) // It's a sunny day for the app.The force will change the appearance of your app immediately including system components and will make run all custom DarkMode code makeUp().
To declare custom DarkMode sensitive code that runs every time if DarkMode Changes register the object or create a DarkMode trigger:
Use Case 1: Register an object to be notified on changes
class DarkModeSensitiveObject {
init() {
DarkModeAgent.register(stakeholder: self, selector: #selector(makeUp))
}
@objc private func makeUp() {
// Runs evary time if Dark Mode changes.
}
}Use Case 2: Create a DarkMode trigger and give it an action
class DarkModeSensitiveObject {
private var theDarknessTrigger = DarkModeObserver()
init() {
theDarnessTrigger.action = { _ in
self.makeUp()
}
}
private func makeUp() {
// Runs evary time if Dark Mode changes.
}
}Use Case: Custom DarkMode sensitive color
import PerseusDarkMode
#if canImport(UIKit)
import UIKit
#elseif canImport(Cocoa)
import Cocoa
#endif
#if os(iOS)
public typealias Color = UIColor
#elseif os(macOS)
public typealias Color = NSColor
#endif
public func rgba255(_ red: CGFloat,
_ green: CGFloat,
_ blue: CGFloat,
_ alpha: CGFloat = 1.0) -> Color {
return Color(red: red/255, green: green/255, blue: blue/255, alpha: alpha)
}
extension Color {
public static var customRed: Color {
return DarkModeAgent.shared.style == .light ?
rgba255(255, 59, 48) : rgba255(255, 69, 58)
}
}And use custom DarkMode sensitive color:
// Runs every time if the DarkMode changes.
// Use KVO (DarkModeObserver) or be registered with DarkModeAgent.
@objc private func makeUp() {
self.backgroundColor = .customRed
}- Preconfigured Swift Package manifest Package.swift
- Preconfigured SwiftLint config .swiftlint.yml
- Preconfigured SwiftLint CI swiftlint.yml
- Preconfigured GitHub config .gitignore
- Preconfigured GitHub CI main.yml
Copyright © 7530 - 7534 Mikhail A. Zhigulin of Novosibirsk
Copyright © 7533 - 7534 PerseusRealDeal
- The year starts from the creation of the world according to a Slavic calendar.
- September, the 1st of Slavic year. It means that "Sep 01, 2024" is the beginning of 7533.
© 2025 The SwiftLint Contributors for SwiftLint
© GitHub for GitHub Action cirruslabs/swiftlint-action@v1
© 2021 Alexandre Colucci, geteimy.com for Shell Script SucceedsPostAction.sh
LICENSE for details.
| Balance and Control | kept by | Mikhail A. Zhigulin |
| Source Code | written by | Mikhail A. Zhigulin |
| Documentation | prepared by | Mikhail A. Zhigulin |
| Product Approbation | tested by | Mikhail A. Zhigulin |
- Language support: Reverso
- Git clients: SmartGit and GitHub Desktop
© Mikhail A. Zhigulin of Novosibirsk.



