web-dev-qa-db-ja.com

iOSアプリにダークモードを追加する

アプリにテーマを追加しようとしています(ダークテーマ)。そのため、ユーザーがアクティビティスイッチをクリックすると、アプリ全体がダークモードになります。ダークモードをハードコーディングしました。しかし、今、私はUISwitchを通してそれを有効および無効にできるようにしたいと思いますが、これを行う方法がわかりませんか?

class DarkModeTableViewCell: UITableViewCell {

var DarkisOn = Bool()
let userDefaults = UserDefaults.standard


@IBOutlet var darkModeSwitchOutlet: UISwitch!

override func awakeFromNib() {
    super.awakeFromNib()


}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}


@IBAction func darkModeSwitched(_ sender: Any) {

    if darkModeSwitchOutlet.isOn == true {

        //enable dark mode

        DarkisOn = true

        userDefaults.set(true, forKey: "DarkDefault")
        userDefaults.set(false, forKey: "LightDefault")



    } else {

        //enable light mode
        DarkisOn = false

        userDefaults.set(false, forKey: "DarkDefault")
        userDefaults.set(true, forKey: "LightDefault")
    }

}



}



class DarkModeViewController: UIViewController {



func set(for viewController: UIViewController) {



    viewController.view.backgroundColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 1.0)
        viewController.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    viewController.navigationController?.navigationBar.tintColor =     UIColor.white
    viewController.navigationController?.navigationBar.barStyle =     UIBarStyle.black
    viewController.tabBarController?.tabBar.barStyle = UIBarStyle.black






}
static let instance = DarkModeViewController()
}

そして、私はビューコントローラのそれぞれで関数を呼び出してそれがどのように見えるかを確認しますが、スイッチがオンまたはオフになっている場合はbool値にアクセスできるようにする必要がありますそうでなければ、物事を同じに保つだけです。さらに質問がある場合は、私に知らせてください、これのいくつかはあまり意味をなさないかもしれません。

12
Jaqueline

更新:この質問(したがって、この回答)はiOS 13が発表される前に書かれたため、iOS 13固有のAPIを使用しません。


これは、通知(NSNotificationCenter AP​​I)を使用して解決します。

これは、ダークモードが有効になっているときと無効になっているときに、View Controllerにリアルタイムで通知することで、リアルタイムで変更に対応できるようにすることです。スイッチの状態などを確認する必要はありません。

2つの通知を作成することから始めます(1つだけで通知を行い、userInfo辞書で目的のテーマを渡すこともできますが、この場合、キャストする必要があるため、2つの通知を作成する方が簡単です。 Swiftで)。

_NotificationsName+Extensions.Swift_:

_import Foundation

extension Notification.Name {
    static let darkModeEnabled = Notification.Name("com.yourApp.notifications.darkModeEnabled")
    static let darkModeDisabled = Notification.Name("com.yourApp.notifications.darkModeDisabled")
}
_

すべての「テーマ対応」View Controllerで、次の通知を聞いてください。

_    override func viewDidLoad() {
        super.viewDidLoad()

        // Add Observers
        NotificationCenter.default.addObserver(self, selector: #selector(darkModeEnabled(_:)), name: .darkModeEnabled, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(darkModeDisabled(_:)), name: .darkModeDisabled, object: nil)
    }
_

無効なオブジェクトに通知を送信すると例外が発生するため、deinitでそれらを削除することを忘れないでください。

_deinit {
    NotificationCenter.default.removeObserver(self, name: .darkModeEnabled, object: nil)
    NotificationCenter.default.removeObserver(self, name: .darkModeDisabled, object: nil)
}
_

「テーマ化可能な」View Controllerで、darkModeEnabled(_:)およびdarkModeDisabled(_:)を実装します。

_@objc private func darkModeEnabled(_ notification: Notification) {
    // Write your dark mode code here
}

@objc private func darkModeDisabled(_ notification: Notification) {
    // Write your non-dark mode code here
}
_

最後に、スイッチを切り替えると、いずれかの通知がトリガーされます。

_@IBAction func darkModeSwitched(_ sender: Any) {

    if darkModeSwitchOutlet.isOn == true {
        userDefaults.set(true, forKey: "darkModeEnabled")

        // Post the notification to let all current view controllers that the app has changed to dark mode, and they should theme themselves to reflect this change.
        NotificationCenter.default.post(name: .darkModeEnabled, object: nil)

    } else {

        userDefaults.set(false, forKey: "darkModeEnabled")

        // Post the notification to let all current view controllers that the app has changed to non-dark mode, and they should theme themselves to reflect this change.
        NotificationCenter.default.post(name: .darkModeDisabled, object: nil)
    }

}
_

これにより、「テーマ」が変更されると、すべてのView Controllerにリアルタイムで通知され、それに応じて反応します。アプリの起動時に適切なモードを表示する手段を講じる必要があることに注意してください。ただし、UserDefaultsを使用し、おそらくそれらをチェックしているので、あなたはそれをしていると確信しています。また、NSNotificationCenterはスレッドセーフではありませんが、とにかくメインスレッドに含まれるすべてのUIコードは重要ではありませんが、言及する価値はあります。

詳細については、 NSNotificationCenter documentation を確認してください。

注:このコードは、OPに基づいて構築されています。単純化することができます(たとえば、「明るい」状態と「暗い」状態の両方を追跡する必要はありません(1つだけ)。

19
Andy Ibanez

アプリをテーマ設定するには、基本的に2つの方法があります。方法1:Appleの IAppearance プロキシを使用します。これは、すべてのビューとコントロールでアプリが色の使用に関して非常に一貫している場合に非常にうまく機能し、例外がたくさんある場合はあまりうまくいきません。その場合、 SwiftTheme のようなサードパーティのポッドを使用することをお勧めします

5
Josh Homann

このアプローチは、Appleによって(ほぼ)すべてのプラットフォームに「ダークモード」をグローバルに導入することに取って代わられていることに注意してください。

3
DrMickeyLauer

IOS 13からAppleダークテーマを起動しました。iOSアプリにダークテーマを追加する場合、viewDidLoad()に次のようなコード行を適用できます。

        if #available(iOS 13.0, *) {
            overrideUserInterfaceStyle = .dark
        } else {
            // Fallback on earlier versions
        }

したがって、テーマは、明るいテーマまたは暗いテーマの2つのオプションがあるように変更できます。ただし、上記のコードを記述している場合、iOS 13を実行しているデバイスでのみ常に暗いテーマが使用されます。

overrideUserInterfaceStyle = .light

または、デバイスがすでにiOS 13で実行されている場合、次のようにテーマを変更できます。

enter image description here

次のような現在の設定テーマを確認することもできます。

if self.traitCollection.userInterfaceStyle == .dark{
    print("Dark theme")
 }else{
    print("Light theme")
}

例を見てみましょう:

override func viewDidLoad() {
       super.viewDidLoad()

       if self.traitCollection.userInterfaceStyle == .dark{
           self.view.backgroundColor = UIColor.black
       }else{
            self.view.backgroundColor = UIColor.white
  }

}

結果:

enter image description here

enter image description here

同じもののビデオは次のとおりです:https://youtu.be/_k6YHMFCpas

1