3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Swift】アラートにAccentColorが適用されない

Last updated at Posted at 2023-11-07

はじめに

アラートにアクセントカラーが適用されてないことに気づきました
その対策を記事にしておきます

追記(2024/1/11)
筆者は記事を書いたとき、マルチモジュール構成のみで発生すると思っていましたが、
マルチモジュール構成とは関係がなく、常に発生しているようです。

https://x.com/noppefoxwolf/status/1745347816892125423?s=20

よって、本記事の再現手順でも再現しますが、ただプロジェクトを作成するだけでも再現するようです。

再現手順

全体像はこんな感じです
スクリーンショット 2023-11-07 22.54.34.png

メインプロジェクトのほうでAssetsにAccentColorを設定しています
スクリーンショット 2023-11-07 22.54.57.png

以下のようにAppFeatureを実装しました

AppFeature.swift
import SwiftUI

public struct AppFeature: App {
    @State private var isPresented = false
    
    public init() {}

    public var body: some Scene {
        WindowGroup {
            Button {
                isPresented.toggle()
            } label: {
                Text("アラート表示")
            }
            .alert("アラート", isPresented: $isPresented) {
                Button {
                    
                } label: {
                    Text("OK")
                }
            }
        }
    }
}

ButtonにAccentColorは効いているようです。

しかし、アラートを表示してみるとボタンが青色で標準のAccentColorから変わってないことがわかります。

アラートのボタンを押したタイミングでAccentColorが反映されています。これは明らかにバグでしょう。

解決方法1

import SwiftUI

public struct AppFeature: App {
    @State private var isPresented = false
    
    public init() {
+      UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = UIColor(named: "AccentColor")
    }

    public var body: some Scene {
        WindowGroup {
            Button {
                isPresented.toggle()
            } label: {
                Text("アラート表示")
            }
            .alert("アラート", isPresented: $isPresented) {
                Button {
                    
                } label: {
                    Text("OK")
                }
            }
        }
    }
}

解決方法2

swiftui-introspectを使用します。

import SwiftUI
import SwiftUIIntrospect

public struct AppFeature: App {
    @State private var isPresented = false
    
    public init() {}

    public var body: some Scene {
        WindowGroup {
            Button {
                isPresented.toggle()
            } label: {
                Text("アラート表示")
            }
            .alert("アラート", isPresented: $isPresented) {
                Button {
                    
                } label: {
                    Text("OK")
                }
            }
+          .introspect(.view, on: .iOS(.v15, .v16, .v17)) { view in
+               view.window?.tintColor = UIColor(named: "AccentColor")
+           }
        }
    }
}

解決後

最初から指定したAccentColorで表示されるようになりました
Simulator Screen Recording - iPhone 15 - 2023-11-07 at 23.06.51.gif

おわり

これは早く治って欲しいですね

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?