Използване на Generics като стойности по подразбиране за свойства на функции в SwiftUI

Опитвам се да разширя протокола 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)

В обобщение, възможно ли е да предоставя стойности по подразбиране за тези генерични продукти, така че да не пиша едни и същи стойности отново и отново в моя код?

Всяка помощ ще бъде оценена.


person PenelopePro    schedule 15.06.2020    source източник


Отговори (1)


Виждам ясно противоречие между използването на генерични продукти и стойностите по подразбиране. Вместо това, защо не създадете обвиваща функция, която предоставя твърдо кодирани стойности на оригиналната функция

@inlinable public func backgroundWithBorder() {
    self.backgroundWithBorder(Circle(), fill: Color.blue, borderStyle: Color.green)
}
person Joakim Danielson    schedule 15.06.2020