Заполните прямоугольник динамического размера радиалградгргрейматом, который идеально подходит, используя Swiftui в SwifIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Заполните прямоугольник динамического размера радиалградгргрейматом, который идеально подходит, используя Swiftui в Swif

Сообщение Anonymous »

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

У меня хорошо работает макет, но градиенты немного разочаровывают. При создании RadialGradient вам необходимо указать beginradius и endradius в фактических точках экрана, а не на единичных точках (от 0,0 до 1,0). /p>

нравится это: < /p>

Код: Выделить всё

RadialGradient(gradient: item.isBlue ? self.blue : self.red,
center: .center,
startRadius: 0.0,
endRadius: 100.0)
В приведенном выше примере я выбрал произвольный размер 100 баллов для endradius . Это работает просто отлично, но на самом деле придает квадратам другой вид, когда они разные размеры. Посмотрите два примера ниже. >

Пример 2 - 2x3 Grid:

< /p>

Вот весь код в примере Project contentView.swift < /strong>, который четко демонстрирует, что я имею в виду: < /p>

import SwiftUI

struct MyDataItem: Identifiable {
let id: UUID = UUID()
let text: String
let isBlue: Bool
}

struct MyDataRow: Identifiable {
let id: UUID = UUID()
let items: [MyDataItem]
}

struct ContentView: View {

@State private var datasetIndex: Int = 0
@State private var sets = [
// First data set
[
MyDataRow(items: [
MyDataItem(text: "A", isBlue: false),
MyDataItem(text: "B", isBlue: true),
MyDataItem(text: "C", isBlue: true),
]),
MyDataRow(items: [
MyDataItem(text: "D", isBlue: false),
MyDataItem(text: "E", isBlue: false),
MyDataItem(text: "F", isBlue: false),
]),
],

// Second data set
[
MyDataRow(items: [
MyDataItem(text: "A", isBlue: false),
MyDataItem(text: "B", isBlue: true),
]),
MyDataRow(items: [
MyDataItem(text: "C", isBlue: true),
MyDataItem(text: "D", isBlue: false),
]),
MyDataRow(items: [
MyDataItem(text: "E", isBlue: false),
MyDataItem(text: "F", isBlue: false),
]),
]
]

var body: some View {
VStack {
Picker(selection: $datasetIndex, label: Text("Pick a data set")) {
Text("Set 1").tag(0)
Text("Set 2").tag(1)
}.pickerStyle(SegmentedPickerStyle())
GridThing(rows: self.$sets[self.datasetIndex])
Spacer()
}
}
}

struct GridThing: View {
@Binding var rows: [MyDataRow]

private let spacing: CGFloat = 20.0

let blue = Gradient(colors: [Color.blue, Color(red: 0.85, green: 0.85, blue: 1.0)])
let red = Gradient(colors: [Color.red, Color(red: 1.0, green: 0.85, blue: 0.85)])

var body: some View {
VStack(alignment: .center, spacing: spacing) {
ForEach(self.rows) { row in
HStack(alignment: .top, spacing: self.spacing) {
ForEach(row.items) { item in
ZStack {
Rectangle()
.fill(RadialGradient(gradient: item.isBlue ? self.blue : self.red,
center: .center,
startRadius: 0.0,
endRadius: 100.0))
.aspectRatio(1.0, contentMode: .fit)
Text(item.text)
.foregroundColor(.black)
}
}
}
}
}
}
}
< /code>

Я хочу, чтобы радиалграграда < /strong> использует эндрадий, который соответствует высоте и ширине квадрата. < /p>
< Br /> Я бы хотел, чтобы он мог сделать это автоматически. LinearGradient
, например, принимает UnitPoint для StartPoint и Endpoint , что было бы идеальным, но для RadialGradient нам нужно выполнить всю работу, я думаю. /p>

Я пытался обернуть его так, рассчитывая endradius < /strong> с помощью geometryReader < /strong>. Этот терпит неудачу, потому что «Компилятор не может проверить это выражение в разумное время; попробуйте разбить выражение на различные подэкспрессии» < /em>: < /p>

var body: some View {
VStack(alignment: .center, spacing: spacing) {
GeometryReader { geom in
ForEach(self.rows) { row in
HStack(alignment: .top, spacing: self.spacing) {
ForEach(row.items) { item in
ZStack {
Rectangle()
.fill(RadialGradient(gradient: item.isBlue ? self.blue : self.red,
center: .center,
startRadius: 0.0,
endRadius: (geom.size.width - (self.spacing * (row.items.count + 1))) / row.items.count))
.aspectRatio(1.0, contentMode: .fit)
Text(item.text)
.foregroundColor(.black)
}
}
}
}
}
}
}
< /code>

Спасибо! < /p>

Подробнее здесь: https://stackoverflow.com/questions/593 ... rfectly-us
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»