Это не имеет ничего общего с .foregroundColor
. Это имеет отношение к .tintColor
и setTitleTextAttributes
.
Этот параметр имеет тип [NSAttributedString.Key : Any]
. Это никоим образом не рассматривает документацию для каждого ключа. Он не знает или не заботится о том, что это должно быть UIColor
. Если вы передадите «squid», это скомпилируется без предупреждения (это не сработает, но скомпилирует):
UIBarButtonItem.appearance().setTitleTextAttributes(
[
.font: UIFont.systemFont(ofSize: 40),
.foregroundColor: "squid",
], for: .normal)
Все, что он смотрит, это то, что вы присваиваете view.tintColor
значение типа Any
.
Проблема в том, что view.tintColor
- это не UIColor
, а UIColor!
. На самом деле .tintColor
не может быть нулем, но возможно установить в ноль:
view.tintColor // r 0.0 g 0.478 b 1.0 a 1.0
view.tintColor = .red
view.tintColor // r 1.0 g 0.0 b 0.0 a 1.0
view.tintColor = nil
view.tintColor // r 0.0 g 0.478 b 1.0 a 1.0
Это имеет смысл в ObjC, но единственный способ выразить это в Swift - это использовать тип !
. Когда вы назначаете !
типы другим вещам, они становятся ?
типами. А это значит, что вы используете UIColor?
в месте, которое принимает Any
(значение словаря).
Использование необязательного значения Any
может быть опасным, поскольку оно создает множество странных угловых случаев. Например, вы не можете совершать обходные действия через Any; он будет раздавлен до базового типа:
let x: Any = Optional(1)
x as? Int? // Cannot downcast from 'Any' to a more optional type 'Int?'
x as? Int // 1
При работе с Any существует множество таких острых кромок.
Конечно, вы не имели ввиду для работы с Any. Это не твоя вина. Но вот почему Свифт жалуется.
Есть несколько решений, в зависимости от того, что вам нравится. Вы можете использовать !
:
.foregroundColor: view.tintColor!
Вы можете добавить as Any
, чтобы отключить предупреждение:
.foregroundColor: view.tintColor as Any
Лично я бы использовал as Any
.
Или вы можете разработать и выгрузить значение раньше (я не рекомендую это):
let tintColor = view.tintColor ?? .blue
UIBarButtonItem.appearance().setTitleTextAttributes(
[
.font: UIFont.systemFont(ofSize: 40),
.foregroundColor: tintColor,
], for: .normal)