(SwiftUI) Как я могу получить доступ к совпадению, которое я нашел из одного массива в другом в ViewBuilder?
У меня два массива.
maschineItems: [MaschineItem]
maschines: [Maschine]
Оба объекта имеют свойство "имя".
В моем представлении я хочу проверить, существует ли имя maschineItem в массиве машин. Я хочу создать "светлый пузырь" для всех maschineItems, который существует в машинах, и "темный пузырь" для всех maschineItems, которого нет в машинах.
Вот мой код (который работает):
import SwiftUI
import Combine
struct OverviewView: View {
@FetchRequest(fetchRequest: MaschineItem.getAllMaschines()) var maschineItems:FetchedResults<MaschineItem>
@State var networkManager = NetworkManager()
var body: some View {
NavigationView{
ScrollView{
VStack(spacing: 30) {
ForEach(maschineItems) { maschineItem in
if NetworkManager.maschines.contains(where: {$0.name == maschineItem.name}) {
BubbleView(locationText: "TEST LOCATION", textIo: "/", textnIo: "/", maschineItem: maschineItem, color: .dividerBackground, opacity: 0.25)
}else {
BubbleView(locationText: "Unknown device", textIo: "/", textnIo: "/", maschineItem: maschineItem, color: .gray, opacity: 0.5)
}
}
}
}
.navigationBarTitle("Übersicht", displayMode: .large)
}
}
Теперь я хочу, чтобы Bubbles содержали информацию о машинах. Так что я должен инициализировать совпадение перед оператором if, не так ли? Но когда я это сделаю:
var body: some View {
NavigationView{
ScrollView{
VStack(spacing: 30) {
ForEach(maschineItems) { maschineItem in
if let maschines = NetworkManager.maschines.first(where: {$0.name == maschineItem.name}) {
BubbleView(locationText: "\(maschines.location.building) / \(maschines.location.workcell)", textIo: "\(maschines.resultCountiO)", textnIo: "\(maschines.location.resultCountniO)", maschineItem: maschineItem, color: .dividerBackground, opacity: 0.5)
}else {
BubbleView(locationText: "Unknown device", textIo: "/", textnIo: "/", maschineItem: maschineItem, color: .gray, opacity: 0.5)
}
}
}
}
.navigationBarTitle("Übersicht", displayMode: .large)
}
}
Я получаю следующую ошибку в строке оператора if:
Closure containing control flow statement cannot be used with function builder 'ViewBuilder'
Как я могу исправить эту проблему? Я много исследовал и нашел похожие темы, которые показали мне, что я должен использоватьarray.first(where: {})
метод, но я не нашел ничего, что помогло бы мне с этой проблемой. И да, я попытался создать функцию, потому что в представлениях неправильная логика. Но когда я пишу все это в функции, возникает та же ошибка.
Я очень благодарен всем, кто пытается мне помочь. PS: Я немец, извините за английский:D
1 ответ
Я бы использовал вычисляемую переменную, которая предоставляет необходимые данные, избегая if let
. В моем примере я добавил вычисляемую переменную (matchedMachines
), который представляет собой массив кортежей. Первое значение в кортеже - этоMachine
пример. Второе значение - этоBool
это указывает на то, была ли найдена машина.
//
// ContentView.swift
// BubbleTest
//
// Created by Paul Wilkinson on 26/6/20.
//
import SwiftUI
struct Machine: Identifiable {
let id = UUID()
let name: String
let colour: String
}
struct ContentView: View {
var machines = [Machine(name: "Bob", colour: "Grey"), Machine(name:"Susan",colour: "Purple"), Machine(name: "Mary", colour: "Red"), Machine(name: "Peter", colour: "Green")]
var names = ["Bob","Mary"]
var matchedMachines: [(Machine,Bool)] {
get {
return machines.map { ($0, names.contains($0.name))
}
}
}
var body: some View {
VStack(spacing:30) {
ForEach(matchedMachines, id: \.0.id ) { machineTuple in
BubbleView(bubbleColor: machineTuple.1 ? .blue:.gray) {
Text(machineTuple.0.name)
Text("Location: \(machineTuple.1 ? "Test Location" : "Location Unknown")")
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct BubbleView<Content: View>: View {
let content: Content
var bubbleColor: Color
init(bubbleColor: Color, @ViewBuilder content: () -> Content) {
self.bubbleColor = bubbleColor
self.content = content()
}
var body: some View {
VStack {
content
}
.padding()
.background(bubbleColor)
.cornerRadius(12.0)
}
}
struct BubbleView_Previews: PreviewProvider {
static var previews: some View {
BubbleView(bubbleColor: .blue) {
Text("Hello world")
}
}
}