Swift / SwiftUI'de birden çok görünüm türü içeren dizi
İnsanların tercih ettikleri arka plan görüntüsünü seçebilecekleri bir görünüm oluşturmak istiyorum, bunlar ön plan rengine sahip bir dikdörtgen veya bir görüntü içerir. Şimdiye kadar bunu oluşturarak çalıştım
Struct:
struct BackgroundImage : Identifiable{
var background : AnyView
let id = UUID()
}
Onları böyle bir diziye ekliyorum
ViewModel:
class VM : ObservableObject{
@Published var imageViews : Array<BackgroundImage> = Array<BackgroundImage>()
init(){
imageViews.append(BackgroundImage(background: AnyView(Rectangle().foregroundColor(Color.green))))
imageViews.append(BackgroundImage(background: AnyView(Rectangle().foregroundColor(Color.yellow))))
imageViews.append(BackgroundImage(background: AnyView(Image("Testimage"))))
}
bu da bir dizi Arka Plan Resimleri arasında döngü yapmamı sağlıyor.
Görünüm:
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) {
ForEach(VM.imageViews, id: \.self.id) { view in
ZStack{
view.background
//.resizable()
//.aspectRatio(contentMode: .fill)
.frame(width: g.size.width/2.25, height: g.size.height/8)
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
}
}
}
Ancak ekleyemiyorum
.resizable()
.aspectRatio(contentMode: .fill)
AnyView buna izin vermediği için görüntüler için.
Bunu başarmanın daha iyi bir yolu var mı? Bunun yerine Şekiller / Görüntüler için sadece iki ayrı dizim mi olmalı? Yoksa buna daha uygun alternatif bir View yapısı var mı?
Teşekkürler!
Yanıtlar
@ DávidPásztor'un yorumlarda bahsettiği gibi Görünümleri ViewModel'inizde saklamak kötü bir tasarımdır.
Gerçekten sadece bir renk ve bir resim adı kaydetmeniz gerekiyor. Görünüm bina kodunun gerçek görünümleri oluşturmasına izin verin.
İşte olası bir uygulama.
struct BackgroundItem: Identifiable {
private let uicolor: UIColor?
private let imageName: String?
let id = UUID()
var isImage: Bool { imageName != nil }
var color: UIColor { uicolor ?? .white }
var name: String { imageName ?? "" }
init(name: String? = nil, color: UIColor? = nil) {
imageName = name
uicolor = color
}
}
class VM : ObservableObject{
@Published var imageItems: [BackgroundItem] = []
init() {
imageItems = [.init(color: .green),
.init(color: .blue),
.init(name: "TestImage")]
}
}
struct ContentView: View {
@ObservedObject var vm = VM()
var body: some View {
GeometryReader { g in
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())]) {
ForEach(vm.imageItems) { item in
ZStack{
if item.isImage {
Image(item.name)
.resizable()
.aspectRatio(contentMode: .fill)
} else {
Color(item.color)
}
}
.frame(width: g.size.width/2.25, height: g.size.height/8)
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous)
}
}
}
}
}
Not:enum
imageName ile renk arasındaki ayrımı saklamak için bir kullanmayı düşündüm , ancak en basitinden sadece isteğe bağlı seçenekleri kullanmak ve ihtiyacım olanı saklamaktı. Görünüm oluşturma koduna maruz kalan arabirimle, uygulamayı, bilgileri depolamak istediğiniz şekilde kolayca değiştirebilirsiniz.