In my "Data.swift" file:struct Legal: Hashable, Codable, Identifiable { var name: String var place: String var category: Category var isFavorite: Bool var penalty: String enum Category: String, CaseIterable, Codable, Hashable { case categoryone = "category One" case categorytwo = "category Two" case categorythree = "category Three" }}In my "legalData.json" file there a several legal provisions following this structure.I want to sort the legal provisions of categoryone in a separate view:Import SwiftUIstruct CategoryoneList: View { @published var legals = legalData var allElements: [Legal] = [] var body: some View { NavigationView { List { ForEach(...) { legal in if !self.userData.showFavoritesOnly || legal.isFavorite { NavigationLink(destination: LegalDetail(legal: legal) .environmentObject(self.userData) ) { LegalRow(legal: legal } } } }}I want to know what I have to type in (...) to have only the legal provisions in this view.Thanks in advance
Post
Replies
Boosts
Views
Activity
thanks for the answer, but it didn't do anything.I'll try to clarify my model (work in progress π).Legal.swift file is structured as follows:struct Legal: Hashable, Codable, Identifiable {
var name: String
var place: String
var category: Category
var isFavorite: Bool
var penalty: String
enum Category: String, CaseIterable, Codable, Hashable {
case categoryone = "category One"
case categorytwo = "category Two"
case categorythree = "category Three"
}
}UserData.swift file is structured as follows:import Combine
import SwiftUI
final class UserData: ObservableObject {
@Published var showFavoritesOnly = false
@Published var legals = legalData
}A few examples from my legal.json file:[
{
"name": "infringement 1",
"category": "Category 1",
"place": "UK",
"id": 7004,
"isFavorite": false,
"penalty": "473 EUR",
},
{
"name": "infringement 2",
"category": "Category 2",
"place": "France",
"id": 1046,
"isFavorite": false,
"penalty": "116 EUR"
}
]Home.swift file = home view is structured as follows:import SwiftUI
struct Home: View {
@EnvironmentObject private var userData: UserData
var body: some View {
NavigationView {
List {
NavigationLink(destination: CategoryoneList()) {
Text("1. Category one")
}
NavigationLink(destination: CategorytwoList()) {
Text("2. Category two")
}
NavigationLink(destination: CategorythreeList()) {
Text("3. Category three")
}
NavigationLink(destination: LegalList()) {
Text("4. Overview").bold().underline()
}
}
.navigationBarTitle("View", displayMode: .inline)
}
}
}LegalList.swift file contains all the legal provisions (disregarding the categories)This is structured as follows:struct LegalList: View {
@EnvironmentObject private var userData: UserData
var body: some View {
List {
Toggle(isOn: $userData.showFavoritesOnly) {
Text("Show Favorites").bold().underline()
}
ForEach(userData.legals) { legal in
if !self.userData.showFavoritesOnly || legal.isFavorite {
NavigationLink(
destination: LegalDetail(legal: legal)
.environmentObject(self.userData)
) {
LegalRow(legal: legal)
}
}
}
}
.navigationBarTitle("4. Overview", displayMode: .inline)
}
}LegalDetail.swift file is structured as follows:struct LegalDetail: View {
@EnvironmentObject var userData: UserData
var legal: Legal
var legalIndex: Int {
userData.legals.firstIndex(where: { $0.id == legal.id })!
}
var body: some View {
List {
VStack {
HStack(alignment: .top) {
Text(legal.name).bold().underline()
}
.padding()
.foregroundColor(Color.green)
Spacer()
VStack(alignment: .leading) {
Text(legal.place)
Divider()
}
Text("Penalty").bold().underline()
.padding()
.foregroundColor(Color.orange)
VStack(alignment: .leading) {
Text(legal.penalty)
Divider()
}
}
}.navigationBarTitle(legal.name)
.navigationBarItems(trailing:
Button(action: {
self.userData.legals[self.legalIndex]
.isFavorite.toggle()
}) {
if self.userData.legals[self.legalIndex]
.isFavorite {
Image(systemName: "star.fill")
.foregroundColor(Color.yellow)
} else {
Image(systemName: "star")
.foregroundColor(Color.gray)
}
}.font(.system(size: 27))
)
}LegalRow.swift file is structured as follows:struct LegalRow: View {
var legal: Legal
var body: some View {
HStack {
Text(legal.name)
Spacer()
if legal.isFavorite {
Image(systemName: "star.fill")
.imageScale(.medium)
.foregroundColor(.yellow)
}
}
}
}The question now is how to make a seperate view for Category one, two and three, with the list of only the legal provisions of that category.Regarding the question of the allElements, this was a suggestion of Claude31.My apologies for the long post and again thanks in advance
Thank you for the answers. It worked for now with the revised code from OOPer.To be complete, the code for legalData was in a different file:import Foundation
import CoreLocation
import UIKit
import SwiftUI
let legalData: [Legal] = load("legalData.json")
func load(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Can't find \(filename) in main bundle")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Can't load \(filename) from main bundleΓ ")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from : data)
} catch {
fatalError("Can't parse \(filename) as \(T.self):\n\(error)")
}
}
I have two follow up questions. If I have to open a new post for these, just let me know.First, I have a problem with some text not being displayed completely (see legal.penalty in the LegalDetail.swift file) in the simulator. From Iphone 8s there is no problem, but on the Iphone 8 the texts are cut and end with [...]Is there any reason why?Second, I want to ad a searchbar on the LegalList view. I try to search on the legal name (the names are displayed in the list).I added in the LegalList.swift:@State privatevar searchTerm: String = ""and under List {SearchBar(text: $searchTerm)in a different file (SearchBar.swift) I have the following code:import Foundation
import SwiftUI
struct SearchBar: UIViewRepresentable {
@Binding var text: String
class Coordinator: NSObject, UISearchBarDelegate {
@Binding var text: String
init(text: Binding) {
_text = text
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
text = searchText
}
}
func makeCoordinator() -> SearchBar.Coordinator {
return Coordinator(text: $text)
}
func makeUIView(context: UIViewRepresentableContext) -> UISearchBar {
let searchBar = UISearchBar(frame: .zero)
searchBar.delegate = context.coordinator
return searchBar
}
func updateUIView(_ uiView: UISearchBar, context: UIViewRepresentableContext) {
uiView.text = text
}
}I suppose that I have to change this code:ForEach(userData.legals) { legal in
if !self.userData.showFavoritesOnly || legal.isFavorite {
NavigationLink(
destination: LegalDetail(legal: legal)
.environmentObject(self.userData)
) {
LegalRow(legal: legal)
but I can't figure out how.I already tried the following:ForEach(userData.legals) {self.search.isEmpty ? true :
$0.localizedCaseInsensitiveContains(self.search)}, id:\.self {Any help is appreciated π
Thank you, this code worked.In the future I will start a new post.