Я пытаюсь написать функцию, которая помещает прямоугольник на экран в уже существующий HStack. Это код без функции (вы можете видеть, что используется повторение кода, помещающее несколько прямоугольников в HStack):
struct ContentView: View {
@State var backgroundHeight = 60.0
@State var backgroundWidth = 60.0
@State var backgroundCorners = 10.0
@State var highlightHeight = 8.0
@State var highlightWidth = 8.0
@State var highlightCorners = 3.0
var body: some View {
Color.blue
.frame(width:backgroundWidth, height:backgroundHeight)
.cornerRadius(backgroundCorners)
.overlay(alignment:.center){
HStack(spacing: 2){
Rectangle()
.foregroundColor(.yellow)
.frame(width:highlightWidth, height:highlightHeight)
.cornerRadius(highlightCorners)
Rectangle()
.foregroundColor(.cyan)
.frame(width:highlightWidth, height:highlightHeight)
.cornerRadius(highlightCorners)
Rectangle()
.foregroundColor(.red)
.frame(width:highlightWidth, height:highlightHeight)
.cornerRadius(highlightCorners)
Rectangle()
.foregroundColor(.white)
.frame(width:highlightWidth, height:highlightHeight)
.cornerRadius(highlightCorners)
}
}
}
}
Этот текст размещает на экране небольшой прямоугольник с наложенными на него прямоугольниками меньшего размера.
Затем я попытался использовать следующую функцию для оптимизации кода (а затем вызвать функцию в HStack):
func quickHighlight {
Rectangle()
.foregroundColor(.yellow)
.frame(width: highlightWidth, height: highlightHeight)
.cornerRadius(highlightCorners)
}
Я пытался вставлять различные перестановки и помещать их в разные части как в коде, так и вне его. Хотя функция, по-видимому, генерирует сообщения об ошибках в зависимости от того, где она находится, например, «Невозможно вывести контекстную базу ...» до «Закрытие, содержащее объявление, не может использоваться с построителем результатов». Загадочная вещь заключается в том, что самая основная функция, которую я использовал в качестве контекстуальной основы для этого обучающего упражнения, казалось, указывала на то, что это должно работать (хотя я уверен, что что-то упущено из виду).
К вашему сведению, моей целью было попробовать оператор case с функцией, где функция получает целое число, а затем выполняет итерацию по нескольким параметрам, чтобы назначить цвет прямоугольнику.
Любая помощь очень ценится.
Стандартный способ — создать подвид. В SwiftUI небольшие представления повышают производительность, поскольку они ужесточают инвалидацию, т. е. требуется только пересчитать функции тела, где фактически изменились lets/vars. Не используйте функцию, которая принимает параметры для возврата представления, потому что это нарушает обнаружение изменений SwiftUI. Модификатор представления — это интересный способ сделать его еще более пригодным для повторного использования. Ниже я продемонстрирую оба способа:
Подвид:
struct HighlightedRectangle: View {
let color: Color
let highlightWidth, highlightHeight, highlightCorners: Float
// body only called if any of the lets are different from last time this View was init by the parent view's body.
var body: some View {
Rectangle()
.foregroundColor(color)
.frame(width: highlightWidth, height: highlightHeight)
.cornerRadius(highlightCorners)
}
}
Затем используйте его в родительском представлении следующим образом
let colors = [.yellow, .cyan, .red, .white]
...
ForEach(colors, id: \.self) { color in {
HighlightedRectangle(color: color, highlightWidth: highlightWidth, highlightHeight: highlightHeight, highlightCorners: highlightCorners)
}
Способ просмотра модификатора:
struct Highlighted: ViewModifier {
let color: Color
let highlightWidth, highlightHeight, highlightCorners: Float
// body only called if any of the lets are different from last time this ViewModifier was init by the parent view's body.
func body(content: Content) -> some View {
content
.foregroundColor(color)
.frame(width: highlightWidth, height: highlightHeight)
.cornerRadius(highlightCorners)
}
}
// this just makes the syntax for using the modifier simpler.
extension View {
func highlighted(color: Color, highlightWidth: Float, highlightHeight: Float, highlightCorners: Float) -> some View {
modifier(Highlighted(color: color, highlightWidth: highlightWidth, highlightHeight: highlightHeight, highlightCorners: highlightCorners))
}
}
Затем используйте его в родительском представлении следующим образом
let colors = [.yellow, .cyan, .red, .white]
...
ForEach(colors, id: \.self) { color in {
Rectangle()
.highlighted(color: color, highlightWidth: highlightWidth, highlightHeight: highlightHeight, highlightCorners: highlightCorners)
}