Post

Replies

Boosts

Views

Activity

Updating a collectionView after dismissing VC
I have a collection view in VC1 embedded in a navigationController. The collection view contains buttons that go to VC2. When make changes in VC2 and close that VC, I want the collectionView in VC1 to update. However, the functions that make up the collectionView aren't inside viewWillAppear; how can I make VC1 refresh after closing VC2? I have tried a few different things written at the bottom of VC2 VC1 import UIKit class HerdViewCell: UICollectionViewCell {     @IBOutlet weak var horseNameOutlet: UILabel!     @IBOutlet weak var baseLayer: UIImageView! } var myHorses = [     Horse(name: "Donnerhall", idNumber: 1, gender: "Stallion", age: 1),     Horse(name: "Celeste", idNumber: 2, gender: "Mare", age: 1),     Horse(name: "Kara", idNumber: 3, gender: "Mare", age: 1) ] var horseIndex = 0 import UIKit class HerdViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {     @IBOutlet weak var herdCollectionView: UICollectionView!     override func viewWillAppear(_ animated: Bool) {         super.viewWillAppear(animated)         herdCollectionView.delegate = self         herdCollectionView.dataSource = self     }     override func viewDidLoad() {         super.viewDidLoad()     }     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) - Int {         return myHorses.count     }     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) - UICollectionViewCell {         var cell = UICollectionViewCell()         if let horseCell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? HerdViewCell {             let horseTag = "\(myHorses[indexPath.row].name ?? "none") \n\(myHorses[indexPath.row].gender), \(myHorses[indexPath.row].age) years"             horseCell.horseNameOutlet.text = horseTag             horseCell.baseLayer.image = myHorses[indexPath.row].basePhenotype             cell = horseCell             horseIndex = indexPath.row         }         return cell     }     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {         horseIndex = indexPath.row         performSegue(withIdentifier: "horseViewerSegue", sender: self)     }     } } VC2 import UIKit class HorseViewController: UIViewController {     @IBOutlet weak var horseNameOutlet: UILabel!     @IBOutlet weak var horseGenderOutlet: UILabel!     @IBOutlet weak var horseAgeOutlet: UILabel!     @IBOutlet weak var baseLayer: UIImageView!     override func viewWillAppear(_ animated: Bool) {         super.viewWillAppear(animated)         updateHorse()     }     override func viewDidLoad() {         super.viewDidLoad()     } }     func updateHorse(){         horseNameOutlet.text = myHorses[horseIndex].name         horseGenderOutlet.text = myHorses[horseIndex].gender         horseAgeOutlet.text = "\(String(myHorses[horseIndex].age)) years"         baseLayer.image = myHorses[horseIndex].basePhenotype      }     @IBAction func sellHorse(_ sender: UIButton) {         myHorses.remove(at: horseIndex) //dismissing won't work, because the app closes the navigationController instead of going back to the root of the navigation controller         //dismiss(animated: true, completion: nil) //If I navigate to the root of the navigationController, the collectionView is as I left it instead of removing a horse //        self.navigationController?.popViewController(animated: true)     } }
11
0
3.1k
Feb ’21
Conditionally changing a value in an array
I am unsure what I am doing wrong here. I want to limit the values in var training to 1.0. I have set up a test where the two printed values should be different, but the value is not changed even though a number higher than 1.0 is found. struct Horse {     var training : [Float] } var myHorses = [     Horse(training: [1.5,0,0,0,0,0,0]),     Horse(training: [0,0,0,0,0,0,0]),     Horse(training: [0,0,0,0,0,0,0]) ] var horseIndex = 0 print(myHorses[horseIndex].training[0]) for var skills in myHorses[horseIndex].training {     if skills 1.0 {         print("value 1.0 found")         skills = 1.0     } } print(myHorses[horseIndex].training[0])
2
0
670
Feb ’21
Changing a value with the stepper
I have a stepper that changes a value in my Horse struct, but at the moment I can only increase the value. I need to "refresh" the page to show the new value in the interface, and that starts the process from scratch. Also, if the horse has a value already the stepper changes it to 0 before proceeding.     func addButtons() {         for (feed,amount) in feedInventory where amount 0 {             let filteredProducts = feedProducts.filter { $0.code.contains(feed)}             for feedProduct in filteredProducts {                 let horizontalStack = UIStackView()                 horizontalStack.axis = .horizontal                 horizontalStack.alignment = .firstBaseline                 let rationAmount = UILabel(frame: .zero)                 let rationIndex = Int(rationArrayPosition[feedProduct.code]!)                 rationAmount.text = "\(myHorses[horseIndex].ration[rationIndex])"                 horizontalStack.addArrangedSubview(rationAmount)                 let stepper = UIStepper(frame: .zero)                 stepper.minimumValue = 0                 stepper.maximumValue = 900                 stepper.wraps = false                 stepper.autorepeat = false                 stepper.addTarget(self, action: #selector(stepperValueChanged(_:)), for: .valueChanged)                 stepper.accessibilityLabel = "\(feedProduct.code)"                 horizontalStack.addArrangedSubview(stepper)                 feedStack.addArrangedSubview(horizontalStack)                 }}}     func removeButtons() {         let rows = feedStack.arrangedSubviews             .filter {$0 is UIStackView}         for row in rows {             feedStack.removeArrangedSubview(row)                 row.removeFromSuperview()             }}         @objc func stepperValueChanged(_ sender:UIStepper!) {         let rationIndex = rationArrayPosition[sender.accessibilityLabel!] //This is where I have trouble*         myHorses[horseIndex].ration[rationIndex ?? 00] += Int(sender.value)         removeButtons()         addButtons()       } I can't use = Int(sender.value) because this resets to 0 each time I press the button, but how can I update the values without using removeButtons() and addButtons()? Let me know if more code is needed, I think I'm just using the stepper incorrectly though
14
0
2.4k
Feb ’21
Adding stacks to a stack view programmatically
I have a stack view to which I add some buttons when the UI loads. I have made these work quite well as they are, but I want to simplify my interface. Instead of showing a button for each feed, I want to add a horizontal stack view showing a label and a stepper to alter the values for each feed type. This is what I have now: struct FeedProduct { var name : String var code : String } var feedProducts = [ FeedProduct(name: "Oats", code: "oats"), FeedProduct(name: "Straw", code: "straw"), FeedProduct(name: "Salt", code: "salt") ] var feedInventory: [ String : Int ] = [     "straw" : 10,     "oats" : 20, "salt" : 0 ] func addButtons() {     for (key,value) in feedInventory{         let button = UIButton()         button.addTarget(self, action: #selector(self.selectFeed(sender:)), for: .touchUpInside)             let filteredProducts = feedProducts.filter { $0.code.contains(key)}             for feedProduct in filteredProducts {                 if value > 0 {                 button.setTitle(" \(feedProduct.name) , amount: \(value)", for: UIControl.State.normal)                         button.accessibilityIdentifier = feedProduct.code                     feedStack.addArrangedSubview(button)                 }}}}     @objc func selectFeed(sender: UIButton){ //this is where assign the selected feed type, and I had an external stepper button to alter the amount of feed }     My plan is to change the addButtons function so that instead of adding buttons, it will add a horizontal stack view containing a label and a stepper for each feed above 0 in the inventory. This would make my interface much cleaner. Not sure if this is even possible, maybe there are better ways of doing it. Any tips would be really helpful!
7
0
3.9k
Feb ’21
Deleting views from a stack view?
I have a stack view to which I programmatically add buttons. There are "tabs" where the user can select different categories. However, when I select a new category, the new buttons are just added underneath. Is there a way to delete the contents of tackStack? Then I could call that function before adding buttons when a new category is selected. I know there is something called removeArrangedSubview, but I am unsure how to use this on buttons that are added programmatically     @IBOutlet weak var tackStack: UIStackView! func addButtons() { for (key,value) in tackInventory{     let button = UIButton()                  button.setTitle("\(foundColor) \(product.brand) \(product.category), amount: \(value)", for: UIControl.State.normal)                 tackStack.addArrangedSubview(button) } }
2
0
1.3k
Jan ’21
Searching for the position of an item in an array within an array?
I have an array of products and a separate dictionary of inventory. I want to be able to use the keys of the dictionary to "look up" the colorName within the product catalog using the name of the item found in the dictionary. I know you can search for item position within an array, but how to you do this if it is an array within an array? The products: Product(brand: "Academia", category: "Bandages", colorName: [ "Blue", "Green", "Purple", "Red" ], item: ["academiaBandagesBlue", "academiaBandagesGreen", "academiaBandagesPurple", "academiaBandagesRed"]) The inventory var tackInventory: [ String : Int] = [    "academiaBandagesBlue" : 1,     "academiaBandagesGreen" : 0,     "academiaBandagesPurple" : 0,     "academiaBandagesRed" : 0
5
0
385
Jan ’21
Search in an array
I can search for a value in an array if I know the position of the item in the array, but how can I search by another parameter like ID number or name? import UIKit struct Horse {     var name : String     var idNumber : Int     var sire : String     var dam : String } var myHorses = [     Horse(name: "Donnerhall", idNumber: 1, sire: "Unknown", dam: "Unknown"),     Horse(name: "Celeste", idNumber: 2, sire: "Unknown", dam: "Unknown"),     Horse(name: "Kara", idNumber: 3, sire: "1", dam: "2"),     ]     func lookupHorse() {         let index = 1         print(myHorses[index].idNumber) print(myHorses[index].name)             }
2
0
779
Jan ’21
Using keypaths to add a value to a variable?
I have had a similar problem previously and someone suggested keypaths might be the answer I want to add to the number of blueBandages struct Product {     var brand: String     var option1: String     var option2: String     var item1: String     var item2: String } //inventory var blueBandages = 0 var redBandages = 0 var yellowBandages = 0 var greenBandages = 0 //catalog let products = [     Product(brand: "Academia", option1: "Blue", option2: "Red", item1: "blueBandages", item2: "redBandages"),     Product(brand: "Academia", option1: "Yellow", option2: "Green", item1: "yellowBandages", item2: "greenBandages")] func buy() { //??? } The obvious way is the following: func buy() { blueBandages += 1 } But this will require a lengthy If statement to identify which item to add. I will have to add to the if statement every time I add an item to the catalog var selectedProduct = 0 if selectedProduct == "Academia blueBandages": blueBandages += 1 I wish I could "unwrap" some string as executable code, but I don't think this exists. func buy() { Code(product[1].item1) =+ 1 } //if only this worked the same as the previous code chunk Maybe keypaths are the answer? I haven't been able to make it work, because my key path is still acting like a string and not executable code
10
0
399
Jan ’21
Calling a property of a struct with a placeholder?
I have a few places in my app where I need to alter a property of a struct, but it takes a lot of code. The struct, arrays and variables: struct Horse { var name: String     var basicTraining : Float     var rhythm : Float     var suppleness : Float var myHorses = [ Horse(name: "Donnerhall", basicTraining : 0.5, rhythm : 0.2, suppleness : 0.1), Horse(name: "Bjork", basicTraining : 0.4, rhythm : 0.3, suppleness : 0.1) ] var horseIndex = 0 var scaleCode = [ basicSkills, rhythmSkills, supplenessSkills ] var currentScaleCode = basicSkills var skillIndex = 0 The current code (takes a lot of lines): func trainHorse() { if myHorses[horseIndex].basicTraining > 100 {                 myHorses[horseIndex].basicTraining = 100 } if myHorses[horseIndex].basicTraining < 100 {                 myHorses[horseIndex].basicTraining += currentScaleCode[skillIndex].basicBoost }                          if myHorses[horseIndex].rhythm > 100 {                 myHorses[horseIndex].rhythm = 100 }             if myHorses[horseIndex].rhythm < 100 {                 myHorses[horseIndex].rhythm += currentScaleCode[skillIndex].rhythmBoost }             if myHorses[horseIndex].suppleness > 100 {                 myHorses[horseIndex].suppleness = 100 }             if myHorses[horseIndex].suppleness < 100 {                 myHorses[horseIndex].suppleness += currentScaleCode[skillIndex].supplenessBoost } } What I would like is to simplify this code by doing something like this: var currentTraining = basicTraining //or rhythm or suppleness currentBoost = basicBoost func trainHorse() { if myHorses[horseIndex].currentTraining > 100 {                 myHorses[horseIndex].currentTraining = 100 } if myHorses[horseIndex].currentTraining < 100 {                 myHorses[horseIndex].currentTraining += currentScaleCode[skillIndex].currentBoost } But when I call a property using a placeholder, I get the error "Value of type 'Horse' has no member..." I have tried using different types of brackets and parentheses without luck
17
0
806
Jan ’21
How to change data in an array using a variable?
I want to change some properties in my array. I recently discovered that I am only able to do this if I directly specify the number of the element in the array I am working with. This is tricky because I always assumed you could edit an array using a variable. I have been using a variable to save myself a lot of code. In some view controllers, the array can have hundreds of items... my var is a workaround that uses the button tag to identify the horse that is selected for editing import UIKit struct Horse{     var name: String     var age: Int } var myHorses = [     Horse(name: "Billy", age: 3),     Horse(name: "Merc", age: 5) ] //horse selected for editing var currentHorse = myHorses[0] //tag of the button that is pressed var horseIndex = sender.tag //trying to edit age currentHorse.age = 10 //I thought these would be the same print(myHorses[1].age) print(merc.age)
3
0
282
Dec ’20
Number variation, but with limits
I want to find a random number in a range that goes 1-100. I want the number to be the average of these two: var firstNumber = 20 var secondNumber = 30 but I want it to have some "variability"         var variability = Int.random(in:-12...12) result: Int.random(in: (firstNumber)...(secondNumber) + variability) The problem is, the result cannot go beyond 1-100. If the first number is close to the end of the range, variability could make the result go beyond 1-100. I tried using an If statement, but this involves writing a lot of extra code for each factor I am adding variability to. Any suggestions?
12
0
497
Dec ’20
Weighted randomisation in swift?
I have a function that calculates a random genotype. At the moment all genes are equally likely. In reality, some genes are more likely than others. How can I change my function to be more realistic? I have attached some example percentages (they don't add up yet)     //grey 10% of "G" appearing, 90% chance of "g" appearing     greGenotype = ["G", "g"][Int.random(in:0...1)]+["G", "g"][Int.random(in:0...1)]     //single tobiano 5% of "To" appearing, 95% of "to" appearing     tobGenotype = ["To", "to"][Int.random(in:0...1)]+["To", "to"][Int.random(in:0...1)]     }
2
0
1.3k
Dec ’20
Find a string within a string?
I have this var: //genes var extGene = "ee" var agoGene = "aa" var creGene = "crcr" //genotype var genotype = extGene + agoGene + creGene The genotype can appear in different variations like "eeaacrcr", "EeAaCrcr" or "EEAACrCr", but there are a lot more combinations. Sometimes the letters in the genes can appear in random order, for example "Ee" or "eE". I am using this switch statement which is getting too complex: switch (extGene, agoGene, creGene) {                 case                 ("EE", "aa", "crcr"),                 ("Ee", "aa", "crcr"),                     ("eE", "aa", "crcr"):                 basPhenotype = (blackArray.randomElement()!)                 case                 ("ee", "aa", "crcr"),                 ("ee", "Aa", "crcr"),                     ("ee", "aA", "crcr"),                 ("ee", "AA", "crcr"):                 basPhenotype = (chestnutArray.randomElement()!)                                          case                 ("EE", "AA", "crcr"),                 ("Ee", "AA", "crcr"),                 ("eE", "AA", "crcr"),                 ("EE", "Aa", "crcr"),                 ("EE", "aA", "crcr"),                 ("Ee", "Aa", "crcr"),                     ("eE", "Aa", "crcr"),                     ("Ee", "aA", "crcr"),                     ("eE", "aA", "crcr"):                 basPhenotype = (bayArray.randomElement()!) Instead it would be nice to just search the genotype for single letters, irrespective of what order they are in, maybe something like this if genotype contains "e" + "E" { uiImage = image1 } if genotype contains "ee" { uiImage = image2 } Does anyone know of a way to simplify the code?
2
0
242
Nov ’20
2-component pickerView with array errors
Hi! I am working on a pickerView with two components. I have an array (myHorses) with one stallion and two mares. If I run the app I get an "out of range" error at line 33. If I add another stallion to the array this goes away. Also, the image outlets are showing the images for the stallion on both outlets. How can I make the app work when there is just one member of a gender, and also show the correct images? class BreedingViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {     let myStallions = myHorses.filter({ $0.gender == "Stallion" })     let myMares = myHorses.filter({ $0.gender == "Mare" })     var sireIndex = 0     var damIndex = 0     @IBOutlet weak var horsePicker: UIPickerView! @IBOutlet weak var sireBaseLayer: UIImageView!     @IBOutlet weak var damBaseLayer: UIImageView!        var recievedString: String = ""     func numberOfComponents(in sirePicker: UIPickerView) -> Int {         return 2     }        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {         if component == 0 {             return myStallions.count         }         else {             return myMares.count         }          }     func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {             let stallions = myStallions[row]             let mares = myMares[row]                    if component == 0 {                 return "\(stallions.name), health: \(stallions.health)"             }             else {                 return "\(mares.name), health: \(mares.health)"             }         }     func pickerView(_ horsePicker: UIPickerView, didSelectRow row: Int, inComponent component: Int) {         var chosenSire = myHorses[sireIndex]         var chosenDam = myHorses[damIndex]         if component == 0 {             let theSire = myHorses[row]             sireNameOutlet.text = theSire.name             chosenSire = theSire   sireBaseLayer.image = chosenSire.basePhenotype         }         else {             let theMare = myHorses[row]             damNameOutlet.text = theMare.name             chosenDam = theMare damBaseLayer.image = chosenDam.basePhenotype         }     }          override func viewDidLoad() {         super.viewDidLoad()         horsePicker.delegate = self         horsePicker.dataSource = self     }      }
2
0
542
Nov ’20
How to get the first bit of an array item with multiple properties?
I have an array: var myHorses = [     Horse(name: "Donnerhall", idNumber: 1, gender: "Stallion"), Horse(name: "Mischa", idNumber: 2, gender: "Mare")] I want to make a picker view with only the names from the array showing. I have previously used button.tag in another VC to find the horseIndex. Is there a way to list only the names in the picker view? func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {         return myHorses[row]         //pasted from another VC, maybe something like this can work here var horseName = for horseIndex in myHorses.indices {         let horse = myHorses[horseIndex]         button.tag = horseIndex     } Thanks in advance!
2
0
339
Oct ’20