How to pass multiple objects to IGListKit Section Controller - ios

I'm using IGListStackedSectionController and I want to know how to pass multiple objects to any of given childs.
I have a scenario like this:
let sectionController = IGListStackedSectionController(sectionControllers: [
WorkingRangeSectionController(),
DisplaySectionController(),
HorizontalSectionController(),
])!
Let's say I want to put a dynamic title on the first section, an array of images in the second section and a different array of images on the last section.
How would I do that?
Thanks a lot!

Short answer:
You can't do this. Same object is passed to all subsection controllers.
Long answer:
You can combine all necessary data to a class, e.g.:
class Model {
var title = ""
var images = [UIImage]()
var otherImages = [UIImage]()
}
You also need to implement IGListDiffable protocol according to your needs.
There is brief example of IGListStackedSectionController in IGListKit examples on GitHub.

Related

How to name an instance of a struct the contents of a variable - Swift

There is almost certainly a better way of doing this and I'd love to know but I can't phrase it in a question so essentially here is my problem:
I am creating an app that presents a list of items(In a table view) which have various bits of data that come along with the item(String Int Date ect). I've decided that the best way to store this data is in a struct because it allows me to store lost of different types of data as well as run processes on it.
The problem is that I want to have theoretically an infinite number of items in the list and so I need to make lost of instances of the Item struct without predetermining the names of each instance.
I would then store these instance names in an array so that they can be listed in the table view.
I'm completely stuck at this point I've spent hours looking and I just can't make sense of it I'm sure its stupidly easy because hundreds of apps must need to do this. I'm Open to anything thanks.
Currently, I have a struct:
struct Item() {
var data1: String
var data2: String // (But Should be Int)
var data3: String
func setDate() {
// code
}
func returnDate() {
// code
}
}
and then in the view controller I have:
#IBAction func SubmitButton(_ sender: UIButton) {
var textField1 = Item(data1: textField1.text!, data2: textFeild2.text!, data3: "Units")
print(textField1.data1)
}
I am not completely sure what your goal is but I guess the final goal is to have an array of your Item Objects, which then can be used to populate an UITableView??? Without setting up a name for this Instances?
The most easiest solution would be to create a array as a Class Property for storing all the Items which is empty like this:
var items : [Item] = []
And then in viewDidLoad(), you can call a function which populates the item array with all the available Items.
This Item Array can then be used to populate the UITableView.
Second Part:
You got this IBAction which creates a new Item. I guess this is supposed to add a new Item to the existing ones.
You can add this new Item to the existing Item Array by using
items.append(Item(<parameters>))
And don't forget to reload the UITableView to include the new data.
tableView.reloadData()

Array Data Through Different View Controllers Swift

Hey guys I'm working on my first ever app and need some help. My workout tracker app has two classes which you can find below. I have two view controllers hooked up to their own swift files.
Heres my first view controller
Basically what it does is takes the data in the text fields and steppers and turns it into a "Workout" object then appends it to the "WorkoutList" class array.
I've got a print statement setup that prints the Array.count. It shows the correct number in the debug but when I switch views it gets reset to zero.
#IBAction func addToWorkoutList(_ sender: UIButton) {
let workout = Workout(name: workoutName.text!, description: workoutDescription.text!, sets: Int(setStepper.text!)!, reps: Int(repStepper.text!)!)
workoutArrayList.append(workout)
print(workoutArrayList.count)
}
The second view inherits the first views class so that is how I access the "WorkoutArrayList"
class OverViewViewController: NewWorkoutViewController, UITableViewDelegate, UITableViewDataSource {
My app basically allows you to add a workout then produces a graph based on the data you provided. This can make it easy to visualize your gains in the gym. I'm doing this as a learning project so any help on what I should do to build this app would also be greatly appreciated.
Workout Object Class
import Foundation
class Workout {
let workoutName : String
let workoutDescription : String
let numberOfSets : Int
let numberOfReps : Int
init(name : String, description : String, sets : Int, reps : Int) {
workoutName = name
workoutDescription = description
numberOfSets = sets
numberOfReps = reps
}
}
WorkoutList Class
import Foundation
class WorkoutList {
let workoutArray : [Workout] = []
}
Inheriting the class is not what you want to do here. An easy fix for you would be to make workoutArray a static variable so any class can access it at any given time.
static var workoutArray : [Workout] = []
Here is why just inheriting the class doesn't work. When the OverViewViewController loads in to the app, it creates a new instance of the class OverViewViewController and since it inherits NewWorkoutViewController, it also creates a new instance of the NewWorkoutViewController class. You have 2 different instances of NewWorkoutViewController, changing a variable in one of those instances won't change it for any other instances of the class. A static variable, however, is what you are looking for. The array can be changed and accessed any time from any class, you don't even need to inherit. It would work whether you made workoutArray static or workoutArrayList static.
If you have any other questions, feel free to leave a comment.

How to Make a Struct Version of the NSCountedSet Class?

I am developing an app in which I need to take two arrays, both holding the same custom data type, MenuItem.
I need to compare them and find the common elements of both arrays.
I compare the two arrays by converting them both to sets and then using the compare function of the set struct.
However, I then need to convert the array of common elements to a Counted Set so that I can find how many of each element exist in the group of common elements.
The problem I am having is with converting the the array of common elements to a Counted Set. In Swift, there is an NSCountedSet class but no CountedSet struct like there are for most built-in swift Data Types:
let groups = Array(self.menu.keys)
//menu and cart are dictionaries the structure [MenuGroup: [MenuItem]]
let cartGroups = Array(self.cart.keys)
let group = groups[indexPath.section]
if cartGroups.contains(group) {
let items = menu[group] as [MenuItem]!
let cartItems = cart[group]
let itemsSet = Set<MenuItem>(items!)
let cartItemsSet = Set<MenuItem>(cartItems!)
let similarSet = itemsSet.intersection(cartItemsSet)
let similarArray = NSMutableArray(Array(similarSet))
let similarCounterSet = NSCountedSet(array: similarArray)
}
I want to create a struct based off the NSCountedSet class so that I can convert the array of common elements to a counted set.
The if statement is for something else, it does not pertain to this question.
Any thoughts on how to do this? If anybody has a different approach to this problem feel free to mention that too.
Thanks,
Simon
Thanks to Martin R I Found An Example of How to do This:
There are various CountedSet implementation available, e.g. https://github.com/0x7fffffff/CountedSet.

Linking 2 strings (or arrays)

I'm trying to make a connection between multiple arrays. Example; (Mario bros)
var names = ["Mario", "Luigi"]
var colors = ["Red", "Green"]
Instead of making if-statements such as if names == "Mario" && colors == "Red" I would like to make an easier connection - just like buttons has tags I would like to make a String-tag ("Mario".tag = 1 and "Red".tag = 1)
Note that I have 10 different arrays such as the above.
Rather than having 10 parallel arrays, I suggest you create a struct with 10 properties, and make an array of those structs.
Structs are a package of data that abstracts away the details of the contents, and lets you deal with the data as a whole.
I would recommend you check out the Swift Programming guide (in its entirity). It's very well written. In particular, here is the page on Classes and Structs.
In addition, if you want to compare one struct to, say, Mario (as you do in your example), you could implement a method == and make your struct conform to the Equatable protocol, which will allow you do something like:
if someCharacter == Mario {... //automatically compares all properties.
See The Swift Programming Language (Swift 2.2) - Protocols.
First of all you need a ModelValue
struct Element {
let name: String
let color: String
}
Now given
let names = ["Mario", "Luigi"]
let colors = ["Red", "Green"]
you can create a list of Element(s).
let elements = zip(names, colors).map { Element(name: $0.0, color: $0.1) }
Finally your can use it
elements[0].name
elements[0].color

It seems like each View Controller is creating a unique instance of my struct - which I don't want?

I'm creating an app in Swift 2.0 xCode7 using the Tabbed-Application template, with each screen having a separate ViewController. I have a struct to manage a variable I want to be accessed by all view controllers. I created the instance of the struct in the first view controller. I'm able to access the struct data and methods in the other views, but if update the data in one view, it doesn't change for all... It's acting as if each View Controller is creating its own instance on its own. I don't want that. I want each ViewController to share the same updated data in the struct. Does this mean that I should be creating a Singleton Pattern? Or, something else? I'm quite new at this, so thanks for your patience.
I'm not sure how exactly you access the structure but it might be that you only need to change struct to class because structs are value types so if you assign it or pass into a method it is copied whereas an instance of a class will avoid copying
Because you didn't give me any code, this is just my guess.
Structs are different from classes. The former stores values and the latter stores references. Let's look at this code:
var obj = SomethingCool()
obj.somethingCooler = 20
var obj2 = obj
obj2.somethingCooler = 10
If SomethingCool were a struct, obj.somethingCooler would still be 20 but obj2.somethingCooler would be 10. On the other hand, if SomethingCool were a class, both obj.somethingCooler and obj2.somethingCooler would be 20.
This is because the third line. The third line is VERY important. If SomethingCool were a struct, the values stored in obj will be copied to obj2. i.e. Two set of independent values would be created. If it were a class, the object that obj will also be referenced by obj2. i.e. There would still be just one object.
Now that you know the difference, I can tell you that you must have done something like the third line in your view controllers, haven't you?
To solve this problem, you can change from a struct to a class. Or you can create something like this:
public class SomeName {
static var myData: SomeTypeOfStruct {
return something
}
}
If you are so hellbent on keeping it as a struct you could do something that swift actually helps u out with.....AppDelegate!
The appdelegate.swift is a single instance object for any application. So in case you want to save a value that you need to access throughout the application or update throughtout the application, you might want to use AppDelegate.
E.g.
In FirstViewController.swift set the AppDelegate variable that you want to reflect on the remaining screens:
(UIApplication.sharedApplication().delegate as! AppDelegate).commonVariableName = NewValueYouWant;
In the SecondViewController.swift, take up that value from the AppDelegate
var updatedValue = (UIApplication.sharedApplication().delegate as! AppDelegate).commonVariableName;
Again...as #Sweeper said, you can always switch to class which is more reliable and used to achieve something like this.
It's acting as if each View Controller is creating its own instance on
its own.
It's all explained in Apple's Swift guide:
Structs:
struct Dog {
var name: String
}
var d1 = Dog(name: "Rover")
var d2 = d1
d2.name = "Sally"
print(d1.name)
print(d2.name)
--output:--
Rover
Sally
Classes:
class Cat {
var name: String = ""
}
var c1 = Cat()
c1.name = "Kitty"
var c2 = c1
c2.name = "Gerald"
print(c1.name)
print(c2.name)
--output:--
Gerald
Gerald
See the difference?

Resources