How to use .contains with array of Struct in SwiftUI? - arrays

I'm trying to check if my appearedNames array already contains my currentPerson string but unfortunately i got this error: Cannot convert value of type 'String?' to expected argument type '(ColoredName) throws -> Bool'... how should i use .contains with a struct?
struct ColoredName: Identifiable {
let id = UUID()
var name: String
var color: Color
}
struct ContentView: View {
#State private var names = ["Steve", "Bill", "Jeff", "Elon"]
#State private var appearedNames = [ColoredName]()
#State private var currentPerson: String?
var body: some View {
NavigationView {
VStack {
NavigationLink("Change view") {
SecondView(appearedNames: $appearedNames)
}
HStack {
Button {
if currentPerson != nil && !appearedNames.contains(currentPerson) // <-- I got the error here {
appearedNames.append(ColoredName(name: currentPerson ?? "", color: .red))
}
changePerson()
} label: {
Text(currentPerson ?? "Start")
.foregroundColor(currentPerson != nil ? .red : .black)
.font(.largeTitle)
}
Button {
if currentPerson != nil {
appearedNames.append(ColoredName(name: currentPerson ?? "", color: .green))
}
changePerson()
} label: {
Text(currentPerson ?? "Start")
.foregroundColor(currentPerson != nil ? .green : .black)
.font(.largeTitle)
}
}
}
}
}
func changePerson() {
if names.count > 0 {
let index = Int.random(in: 0..<names.count)
currentPerson = names[index]
names.remove(at: index)
}
}
}
struct SecondView: View {
#Binding var appearedNames: [ColoredName]
var body: some View {
VStack {
ForEach(appearedNames) { person in
Text(person.name)
.foregroundColor(person.color)
.font(.largeTitle)
.bold()
}
}
}
}

try something like this, where you compare the name of the ColoredName in the array, with the String currentPerson (unwrapped):
if currentPerson != nil && !appearedNames.contains(where: { $0.name == currentPerson!} ) {
appearedNames.append(ColoredName(name: currentPerson ?? "", color: .red))
}
or, alternatively:
if let theName = currentPerson, !appearedNames.contains(where: { $0.name == theName} ) {
appearedNames.append(ColoredName(name: theName, color: .red))
}

Related

Sort the array alphabetically. Output an array in sections split alphabetically. SwiftUI [duplicate]

How can I make a Form in which the elements are automatically divided into sections based on their first letter and add to the right the alphabet jumper to show the elements starting by the selected letter (just like the Contacts app)?
I also noted a strange thing that I have no idea how to recreate: not all letters are shown, some of them appear as "•". However, when you tap on them, they take you to the corresponding letter anyway. I tried using a ScrollView(.vertical) inside a ZStack and adding .scrollTo(selection) into the action of the Buttons, however 1) It didn't scroll to the selection I wanted 2) When I tapped on the "•", it was as if I was tapping on all of them because they all did the tapping animation 3) I wasn't able to divide the List as I wanted to.
I have this:
import SwiftUI
struct ContentView: View {
let alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", "X","Y", "Z"]
let values = ["Avalue", "Bvalue", "Cvalue", "Dvalue"]
var body: some View {
ScrollViewReader{ scrollviewr in
ZStack {
ScrollView(.vertical) {
VStack {
ForEach(alphabet, id: \.self) { letters in
Button(letters){
withAnimation {
scrollviewr.scrollTo(letters)
}
}
}
}
}.offset(x: 180, y: 120)
VStack {
ForEach(values, id: \.self){ vals in
Text(vals).id(vals)
}
}
}
}
}
}
But I'd want it like this:
import SwiftUI
struct AlphabetSort2: View {
let alphabet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", "X","Y", "Z"]
let values = ["Avalue", "Bvalue", "Cvalue", "Dvalue", "Mvalue", "Zvalue"]
var body: some View {
ScrollView {
ScrollViewReader { value in
ZStack{
List{
ForEach(alphabet, id: \.self) { letter in
Section(header: Text(letter)) {
ForEach(values.filter { $0.hasPrefix(letter) }, id: \.self) { vals in
Text(vals).id(vals)
}
}.id(letter)
}
}
HStack{
Spacer()
VStack {
ForEach(0..<alphabet.count, id: \.self) { idx in
Button(action: {
withAnimation {
value.scrollTo(alphabet[idx])
}
}, label: {
Text(idx % 2 == 0 ? alphabet[idx] : "\u{2022}")
})
}
}
}
}
}
}
}
}
struct AlphabetSort2_Previews: PreviewProvider {
static var previews: some View {
AlphabetSort2()
}
}
Add an swipe-up-and-down action for the alphabet jumper, so we can get an UILocalizedIndexCollation -like swipe effect, it works for view and add mode, but delete, I guess it is due to SwiftUI's UI refresh mechanism.
extension String {
static var alphabeta: [String] {
var chars = [String]()
for char in "abcdefghijklmnopqrstuvwxyz#".uppercased() {
chars.append(String(char))
}
return chars
}
}
struct Document: View {
#State var items = ["Alpha", "Ash", "Aman", "Alisia", "Beta", "Baum", "Bob", "Bike", "Beeber", "Beff", "Calipha", "Cask", "Calf", "Deamon", "Deaf", "Dog", "Silk", "Seal", "Tiger", "Tom", "Tan", "Tint", "Urshinabi", "Verizon", "Viber", "Vein", "Wallet", "Warren", "Webber", "Waiter", "Xeon", "Young", "Yoda", "Yoga", "Yoger", "Yellow", "Zeta"]
var body: some View {
ScrollViewReader { scrollView in
HStack {
List {
ForEach(String.alphabeta, id: \.self){ alpha in
let subItems = items.filter({$0.starts(with: alpha)})
if !subItems.isEmpty {
Section(header: Text(alpha)) {
ForEach(subItems, id: \.self) { item in
Text(item)
}.onDelete(perform: { offsets in
items.remove(at: offsets.first!)
})
}.id(alpha)
}
}
}
VStack{
VStack {
SectionIndexTitles(proxy: scrollView, titles: retrieveSectionTitles()).font(.footnote)
}
.padding(.trailing, 10)
}
}
}
// .navigationBarTitleDisplayMode(.inline)
// .navigationBarHidden(true)
}
func retrieveSectionTitles() ->[String] {
var titles = [String]()
titles.append("#")
for item in self.items {
if !item.starts(with: titles.last!){
titles.append(String(item.first!))
}
}
titles.remove(at: 0)
if titles.count>1 && titles.first! == "#" {
titles.append("#")
titles.removeFirst(1)
}
return titles
}
}
struct Document_Previews: PreviewProvider {
static var previews: some View {
Document()
}
}
struct SectionIndexTitles: View {
class IndexTitleState: ObservableObject {
var currentTitleIndex = 0
var titleSize: CGSize = .zero
}
let proxy: ScrollViewProxy
let titles: [String]
#GestureState private var dragLocation: CGPoint = .zero
#StateObject var indexState = IndexTitleState()
var body: some View {
VStack {
ForEach(titles, id: \.self) { title in
Text(title)
.foregroundColor(.blue)
.modifier(SizeModifier())
.onPreferenceChange(SizePreferenceKey.self) {
self.indexState.titleSize = $0
}
.onTapGesture {
proxy.scrollTo(title, anchor: .top)
}
}
}
.gesture(
DragGesture(minimumDistance: indexState.titleSize.height, coordinateSpace: .named(titles.first))
.updating($dragLocation) { value, state, _ in
state = value.location
scrollTo(location: state)
}
)
}
private func scrollTo(location: CGPoint){
if self.indexState.titleSize.height > 0{
let index = Int(location.y / self.indexState.titleSize.height)
if index >= 0 && index < titles.count {
if indexState.currentTitleIndex != index {
indexState.currentTitleIndex = index
print(titles[index])
DispatchQueue.main.async {
let impactMed = UIImpactFeedbackGenerator(style: .medium)
impactMed.impactOccurred()
// withAnimation {
proxy.scrollTo(titles[indexState.currentTitleIndex], anchor: .top)
// }
}
}
}
}
}
}
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}
struct SizeModifier: ViewModifier {
private var sizeView: some View {
GeometryReader { geometry in
Color.clear.preference(key: SizePreferenceKey.self, value: geometry.size)
}
}
func body(content: Content) -> some View {
content.background(sizeView)
}
}

SwiftUI delete rows from a list

As you can see from the image I have a list of colors, I would like to be able to also give the possibility to delete a color from the array.
I tried to add a list and then call the onDelete call on ForEach, but it's not working well it gives me problems.
Then in addition to this I would like the list to be the size of the contained elements.
Error:
Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444
Can anyone give me some advice?
Code:
import SwiftUI
struct ContentView: View {
var cornerRadius: CGFloat = 16
#State public var select = 2
#State public var bgColors: [Color] =
[
Color(red: 21.0/255.0, green: 101.0/255.0, blue: 192.0/255.0),
Color(red: 255.0/255.0, green: 193.0/255.0, blue: 7.0/255.0),
Color(red: 76.0/255.0, green: 175.0/255.0, blue: 80.0/255.0)
]
#Environment(\.colorScheme) var colorScheme
#State var isShowPicker: Bool = false
#State var image: Image? = Image("placeholder")
#State private var url: String = "https://a.wattpad.com/useravatar/climaxmite.256.718018.jpg"
init() {
// Segmented control colors
UISegmentedControl.appearance().backgroundColor = .systemGray6
UISegmentedControl.appearance().selectedSegmentTintColor = UIColor(Color.blue)
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.systemBackground], for: .selected)
UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.label], for: .normal)
}
var body: some View {
VStack{
ZStack {
RoundedRectangle(cornerRadius: cornerRadius)
.frame(width: UIScreen.main.bounds.width-40, height: 100, alignment: .center)
.foregroundColor(colorScheme == .dark ? .black : .white)
VStack(spacing: 12) {
ZStack {
Rectangle()
.frame(width: UIScreen.main.bounds.width-47, height: 35, alignment: .center)
.foregroundColor(Color(UIColor.systemGray6))
.cornerRadius(cornerRadius, corners: [.topLeft, .topRight])
Text("Select Background")
.foregroundColor(Color(UIColor.label))
.font(.subheadline)
.bold()
}
Picker(selection: $select, label: Text("Select Background")) {
Text("Url").tag(0)
Text("Select Image").tag(1)
Text("Gradient").tag(2)
}.pickerStyle(SegmentedPickerStyle())
.padding(EdgeInsets(top: 0, leading: 30, bottom: 0, trailing: 30))
Spacer()
.frame(height: 3)
}
}
if self.select == 0 {
VStack{
ZStack {
RoundedRectangle(cornerRadius: cornerRadius)
.frame(width: UIScreen.main.bounds.width-40, height: 42, alignment: .center)
.foregroundColor(Color(UIColor.systemBackground))
TextField("http://", text: $url)
.padding(10)
.frame(width: UIScreen.main.bounds.width-40)
.foregroundColor(Color(UIColor.label))
.cornerRadius(cornerRadius)
.padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 10))
}
Button(action: {
}, label: {
Text("Submit")
.foregroundColor(Color(UIColor.systemBackground))
.bold()
})
.padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 20))
.foregroundColor(.white)
.font(.subheadline)
.background(Color.blue)
.cornerRadius(cornerRadius)
}
}
if self.select == 1 {
VStack {
Button(action: {
withAnimation {
self.isShowPicker.toggle()
}
}) {
Image(systemName: "photo")
.font(.headline)
.foregroundColor(colorScheme == .dark ? .white : .black)
Text("Import")
.font(.headline)
.foregroundColor(colorScheme == .dark ? .white : .black)
}
.foregroundColor(.black)
}
.sheet(isPresented: $isShowPicker) {
ImagePicker(image: self.$image)
}
}
if self.select == 2 {
VStack(alignment: .trailing){
Button(action: {
bgColors.append(Color.clear)
}) {
Image(systemName: "plus")
.font(.headline)
.foregroundColor(colorScheme == .dark ? .white : .black)
.padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 15))
}
List {
ForEach(Array(bgColors.enumerated()), id: \.offset) { index, element in
ZStack {
ColorPicker("Set the background color", selection: $bgColors[index])
}
.padding(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 10))
} .onDelete(perform: delete)
}.background(Color.blue)
}
}
Spacer()
}
.padding(.top, 25)
.ignoresSafeArea(.keyboard)
.background(Color(UIColor.systemGray6))
.edgesIgnoringSafeArea(.all)
}
func delete(at offsets: IndexSet) {
bgColors.remove(atOffsets: offsets)
}
}
struct RoundedCorner: Shape {
var radius: CGFloat = .infinity
var corners: UIRectCorner = .allCorners
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}
extension View {
func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
clipShape( RoundedCorner(radius: radius, corners: corners) )
}
}
// extension for keyboard to dismiss
extension UIApplication {
func endEditing() {
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
struct ImagePicker: UIViewControllerRepresentable {
#Environment(\.presentationMode)
var presentationMode
#Binding var image: Image?
class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
#Binding var presentationMode: PresentationMode
#Binding var image: Image?
init(presentationMode: Binding<PresentationMode>, image: Binding<Image?>) {
_presentationMode = presentationMode
_image = image
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
image = Image(uiImage: uiImage)
presentationMode.dismiss()
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
presentationMode.dismiss()
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(presentationMode: presentationMode, image: $image)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController,
context: UIViewControllerRepresentableContext<ImagePicker>) {
}
}
The problem is that in your List, the id you give it is \.offset. However, since you are removing data from bgColors, so this data can change. Instead, you should set the id as \.element because it will be constant for each color.
Consider this simplified example, which crashes when you remove a Color from the list:
struct ContentView: View {
#State private var arr: [Color] = [.red, .green, .blue]
var body: some View {
List {
ForEach(Array(arr.enumerated()), id: \.offset) { (index, _) in
ColorPicker("Color", selection: $arr[index])
}
.onDelete(perform: delete)
}
}
private func delete(at offsets: IndexSet) {
arr.remove(atOffsets: offsets)
}
}
And the working example, where the changes are the id given to the List, and the new Binding to the color (note the custom Binding for the selection):
struct ContentView: View {
#State private var arr: [Color] = [.red, .green, .blue]
var body: some View {
List {
ForEach(Array(arr.enumerated()), id: \.element) { (index, _) in
ColorPicker(
"Color",
selection: Binding<Color>(
get: { arr[index] },
set: { arr[index] = $0 }
)
)
}
.onDelete(perform: delete)
}
}
private func delete(at offsets: IndexSet) {
arr.remove(atOffsets: offsets)
}
}

After appending element to array it should show more elements

This is how it looks before and after..
I have a ForEach Loop, and when I click on the card, it appends a new element to the array and then IT SHOULD SHOW 2 CARDS.
But there is still one card. (but I appended the new card element)
So what should I do?
struct TimelineFromUserView: View {
var card: [Card] = cardData
var body: some View {
VStack {
HStack {
Text("History").bold()
.font(.largeTitle)
.padding(.top, 20)
.padding(.leading, 20)
Spacer()
}
Divider()
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 30) {
ForEach(card) { item in
CardForTimeline(card: item)
.onTapGesture {
print("juhuu")
cardData.append(Card(number: 2, start: "01.10.2021", end: "20.10.2021", days: 19, success: false))
print(cardData)
}
.padding()
}
}
.padding(.top, 10)
}
}
}
}
struct Card: Identifiable{
var id = UUID()
var number: Int
var start: String
var end: String
var days: Int
var success: Bool
}
var cardData: [Card] = [
Card(number: 1 ,start: "05.06.2020", end: "15.06.2020", days: 10, success: true)
]
You only pass a copy card of the array cardData into the ForEach but if I understand your code snippets correctly it should be the original array cardData.
If that's not the problem it would be helpful to post more of your code.
I just replace CardForTimeline on Text (because I didn't have your CardForTimeline) and it return me 2 (also I replaced print(cardData) on print(cardData.count)). You can create fully new project and add this code. It will print 2, 3, 4, 5 after taps
struct ContentView: View {
var card: [Card] = cardData
var body: some View {
VStack {
HStack {
Text("History").bold()
.font(.largeTitle)
.padding(.top, 20)
.padding(.leading, 20)
Spacer()
}
Divider()
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 30) {
ForEach(card) { item in
Text(verbatim: "we")
.onTapGesture {
print("juhuu")
cardData.append(Card(number: 2, start: "01.10.2021", end: "20.10.2021", days: 19, success: false))
print(cardData.count)
}
.padding()
}
}
.padding(.top, 10)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Card: Identifiable{
var id = UUID()
var number: Int
var start: String
var end: String
var days: Int
var success: Bool
}
var cardData: [Card] = [
Card(number: 1 ,start: "05.06.2020", end: "15.06.2020", days: 10, success: true)
]
the problem is that SwiftUI does not know to update the view. Try writing
#State private var card: [Card] = [
Card(number: 1 ,start: "05.06.2020", end: "15.06.2020", days: 10, success: true)
]
instead of: var card: [Card] = cardData.
This should work because then you are telling SwiftUI that it should update the view whenever the value changes.
Additionally you would have to change the adding part of your code to this:
.onTapGesture {
self.card.append(Card(number: 2, start: "01.10.2021", end: "20.10.2021", days: 19, success: false))
}
The above is an approach using a local #State property to manage the state. You could also use a observable object with an array of cards instead. This could look like this:
struct ContentView: View {
#ObservedObject private var cardData = CardData()
var body: some View {
VStack {
HStack {
Text("History").bold()
.font(.largeTitle)
.padding(.top, 20)
.padding(.leading, 20)
Spacer()
}
Divider()
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 30) {
ForEach(cardData.cards) { card in
Text(card.id.uuidString)
.onTapGesture {
self.cardData.add(card: Card(number: 2, start: "01.10.2021", end: "20.10.2021", days: 19, success: false))
}
.padding()
}
}
.padding(.top, 10)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Card: Identifiable{
var id = UUID()
var number: Int
var start: String
var end: String
var days: Int
var success: Bool
}
class CardData: ObservableObject {
// store the cards and make sure its get-only from the outside
#Published private(set) var cards = [
Card(number: 1 ,start: "05.06.2020", end: "15.06.2020", days: 10, success: true)
]
// MARK: - Intents for modifing the cards, add additional if needed
func add(card: Card) {
self.cards.append(card)
}
}
I hope this will help you with your problems

parse containedIn query returns nothing

The following are my codes:
var food = [chicken, fish, duck, pork]
var recipeNames = [String]()
var recipePictures = [UIImage]()
func getRecipes() {
let getRecipesQuery = PFQuery(className: "recipes")
getRecipesQuery.whereKey("food", containedIn: food)
getRecipesQuery.findObjectsInBackgroundWithBlock { (recipes, error) -> Void in
if let recipes = recipes {
self.recipeNames.removeAll(keepCapacity: true)
self.recipePictures.removeAll(keepCapacity: true)
for recipe in recipes {
self.recipeNames.append(recipe["name"] as! String)
if let recipePictureFile = recipe["pictureFile"] as? PFFile {
recipePictureFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in
if error == nil {
if let picture = UIImage(data: imageData!) {
self.recipePictures.append(picture)
}
}
})
}
}
}
print(self.recipeNames.count)
print(self.recipePictures.count)
}
}
I printed the two arrays counts at the end to check if anything is fetched, the counts are both 0. Any idea why this is happening? There are definitely objects in the class which keys "food" equal to one of the objects in the "food" array, thanks!
EDIT
func getRecipes() {
let getRecipesQuery = PFQuery(className: "recipes")
getRecipesQuery.whereKey("food", containedIn: food)
getRecipesQuery.findObjectsInBackgroundWithBlock { (recipes, error) -> Void in
if let recipes = recipes {
self.recipeNames.removeAll(keepCapacity: true)
self.recipePictures.removeAll(keepCapacity: true)
for recipe in recipes {
self.recipeNames.append(recipe["name"] as! String)
if let recipePictureFile = recipe["pictureFile"] as? PFFile {
recipePictureFile.getDataInBackgroundWithBlock({ (imageData, error) -> Void in
if error == nil {
if let picture = UIImage(data: imageData!) {
self.recipePictures.append(picture)
}
}
})
}
}
dispatch_async(dispatch_get_main_queue()) {
self.recipesTableView.reloadData()
}
}
}
}

Adding data to arrays in swift

I am trying to append data to an Array and save using TMCache, but it's like I'm doing it wrong. Cause, the data isn't being appended. I keep getting empty array
private var teams: Array<Teams> = Array<Teams>()
private var teamResults: [TeamResult]! {
didSet {
if teamResults.count <= 0 {
return
} else {
self.teams = []
for var index = 0; index < teamResults.count; index++ {
//print(index)
let categoryResult = teamResults[index]
if let categoryBackgroundImage = categoryResult["image"] as? PFFile {
categoryBackgroundImage.getDataInBackgroundWithBlock({ (data, error) -> Void in
if let dataGot = data {
let image = UIImage(data: dataGot)
let appendData = Teams(playing: categoryResult["playing"] as! Bool,
name: categoryResult["name"] as! String,
position: categoryResult["position"] as! Int,
image: image!)
//print(appendData.position)
self.teams.append(appendData)
}
print(self.teams.count) <-- I get 0
})
print(self.teams.count) <-- I get 0
}
}
TMCache.sharedCache().setObject(self.teams, forKey: "Teams")
self.mainTableView.reloadData()
for categ in teams {
print(categ.position)
}
}
}
}
getDataInBackgroundWithBlock works asynchronously. The data is returned later in the block.
You have to put the code to reload the table view into the block and check if the loop is finished.
For example (untested)
private var teams: Array<Teams> = Array<Teams>()
private var teamResults: [TeamResult]! {
didSet {
if teamResults.count <= 0 {
return
} else {
self.teams = []
var index : Int
for index = 0; index < teamResults.count; index++ {
//print(index)
let categoryResult = teamResults[index]
if let categoryBackgroundImage = categoryResult["image"] as? PFFile {
categoryBackgroundImage.getDataInBackgroundWithBlock({ (data, error) -> Void in
if let dataGot = data {
let image = UIImage(data: dataGot)
let appendData = Teams(playing: categoryResult["playing"] as! Bool,
name: categoryResult["name"] as! String,
position: categoryResult["position"] as! Int,
image: image!)
//print(appendData.position)
self.teams.append(appendData)
TMCache.sharedCache().setObject(self.category, forKey: "Teams")
if index == teamResults.count {
self.mainTableView.reloadData()
for categ in teams {
print(categ.position)
}
}
}
})
}
}
}
}
}

Resources