Я пытаюсь расширить протокол SwiftUI View, чтобы упростить свой код. Я создал функцию «Просмотр» для установки отступов, фона, наложения и тени вместо того, чтобы писать все эти модификаторы каждый раз в моем проекте.

@inlinable public func backgroundWithBorder<Background: Shape, S: ShapeStyle>(
                                                _ background: Background,
                                                fill: S,
                                                borderStyle: S,
                                                borderWidth: CGFloat = 2, 
                                                shadow: Bool = false) -> some View {

        self
            .padding()
            .background(background.fill(fill))
            .overlay(background.stroke(borderStyle, lineWidth: borderWidth))
            .shadow(color: shadow ? Color.primary.opacity(0.2) : Color.clear, radius: 20, x: 0, y: 0)

    }

Приведенный выше код работает должным образом, однако я хотел бы предоставить значения по умолчанию для общих типов "Фон" и "S", например ...

@inlinable public func backgroundWithBorder<Background: Shape, S: ShapeStyle>(
                                                    _ background: Background = Circle(),
                                                    fill: S = Color.blue,
                                                    borderStyle: S = Color.green,
                                                    borderWidth: CGFloat = 2, 
                                                    shadow: Bool = false) -> some View

Примечание. Я использую универсальные шаблоны, потому что мне не всегда нужна одна и та же форма, а в некоторых случаях я хочу использовать градиентную заливку.

Когда я добавляю эти значения по умолчанию, я получаю сообщение об ошибке

Значение аргумента по умолчанию типа «Круг» не может быть преобразовано в тип «Фон» «Вставить как! Фон»

Значение аргумента по умолчанию типа "Цвет" не может быть преобразовано в тип "S" "Вставить" как! S "

Когда я это сделаю, ошибки исчезнут внутри расширения

@inlinable public func backgroundWithBorder<Background: Shape, S: ShapeStyle>(
                                                _ background: Background = Circle() as! Background,
                                                fill: S = Color.blue as! S,
                                                borderStyle: S = Color.blue as! S,
                                                borderWidth: CGFloat = 2, 
                                                shadow: Bool = false) -> some View {

Однако в ContentView я получаю сообщение об ошибке ...

VStack {
    Text("Hello")
    Text("World")
}
.backgroundWithBorder()

Не удалось вывести общий параметр "Фон".

Не удалось сделать вывод о универсальном параметре "S"

Опять же, если я предоставляю значения, а не использую входной параметр по умолчанию, он строится и работает отлично.

VStack {
    Text("Hello")
    Text("World")
}
.backgroundWithBorder(Circle(),
                      fill: Color.blue,
                      borderStyle: Color.green,
                      shadow: true)

Таким образом, можно ли предоставить значения по умолчанию для этих универсальных шаблонов, чтобы я не записывал одни и те же значения снова и снова в свой код?

Любая помощь была бы признательна.

1
PenelopePro 15 Июн 2020 в 08:57

1 ответ

Лучший ответ

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

@inlinable public func backgroundWithBorder() {
    self.backgroundWithBorder(Circle(), fill: Color.blue, borderStyle: Color.green)
}
0
Joakim Danielson 15 Июн 2020 в 06:27