`.background` не работает в модификаторе `.background()` в SwiftUI

Я пытаюсь создать ButtonStyle. Я хочу, чтобы цвет фона был buttonBackgroundHover цветом, который уже создан в Assets.xcassets, а в остальное время остается цветом фона по умолчанию (таким же, как цвет фона окна). Итак, я попробовал код ниже, но Xcode выдал ошибку: Member 'background(ignoresSafeAreaEdges:)' expects argument of type 'Color'

struct PlayerButton: ButtonStyle {

    @State private var isOnHover: Bool = false

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .background(isOnHover ? Color("buttonBackgroundHover") : .background)
    }
}

Но если я заменю .background(isOnHover ? Color("buttonBackgroundHover") : .background) на .background(.background), спору нет. Интересно, что с этим не так и как я могу решить эту проблему. Я был бы признателен за вашу помощь.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
43
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Нет цвета Color.background - он пытается применить тот же модификатор .background(), но в тернарном операторе сначала стоит Color, поэтому конфликт типов - ошибка.

Я предполагаю, что это было ожидаемо

.background(isOnHover ? Color("buttonBackgroundHover") : 
                        Color(uiColor: UIColor.systemBackground))  // << this !!

Спасибо. Но что, если моя цель — macOS. Поскольку UIKit нельзя использовать для macOS, и все .textBackgroundColor, .controlBackgroundColor, .underPageBackgroundColor и .windowBackgroundColor в NSColor имеют тонкое отличие от реального цвета фона моего окна. Есть ли решение?

Yiming Designer 11.05.2022 14:36

Вы должны были упомянуть, что это для macOS, в любом случае найдите цвет, который соответствует вашим потребностям, но на самом деле это другой вопрос.

Asperi 11.05.2022 14:57
Ответ принят как подходящий

Метод background объявляется следующим образом:

func background<S>(_ style: S, ignoresSafeAreaEdges edges: Edge.Set = .all) -> some View where S : ShapeStyle

Обратите внимание, что аргумент, который он принимает, имеет тип S, где S : ShapeStyle. Когда вы делаете .background(.red) или .background(.background), S это Color или BackgroundStyle соответственно.

Однако при входе:

isOnHover ? Color("buttonBackgroundHover") : .background

Нет единого типа S, который работает. Вы хотите, чтобы S было либоColorилиBackgroundStyle, но тип приведенного выше выражения может быть только одним типом этих типов. Компилятор видит, что поскольку Color("buttonBackgroundHover") имеет тип Color, он ошибочно считает, что вы хотите, чтобы третий операнд .background тоже имел тип Color. Но такого свойства, как Color.background, нет, но поскольку Color — это представление, у него тоже есть background метод, и именно к нему разрешается .background. Он ожидает аргумент Color, потому что вы вызываете метод экземпляра без экземпляра (Color.background).

Во всяком случае, есть ластик типа для ShapeStyle - AnyShapeStyle. Примените это, чтобы сделать обе ветви условного выражения одного типа:

.background(isOnHover ? AnyShapeStyle(Color("buttonBackgroundHover")) : AnyShapeStyle(.background))

Другие вопросы по теме