Search code examples
iosswiftuitableviewuikituistackview

UIStackViews are collapsing inside of another UIStackView and TableView


Pretty new to this so I appreciate any and all help here.

I've spent a lot of time perusing the web and trying different solutions but I'm at a loss.

I'm using tableView to populate events within a view. These events can have multiple participants (2 - 8) The participants (and other objects) are represented by sub-stackviews and I control whether or not to display stackView7, stackView8, etc. based on the count of an array of participants.

For some reason, sometimes, one or a few of the participant stackViews is being crushed to a smaller size.

I'm sorry there's so much code attached but I'm really not sure what will be relevant.

Thank you in advance and let me know if different code is needed for context

Image with error

Image as it should be

Example of stackView layout

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "challengeCell", for: indexPath)
        
        let participant1Photo = cell.viewWithTag(10) as! UIImageView
        let participant1Name = cell.viewWithTag(11) as! UILabel
        
        let participant2Photo = cell.viewWithTag(20) as! UIImageView
        let participant2Name = cell.viewWithTag(21) as! UILabel
        
        let participant3Stack = cell.viewWithTag(3)
        let participant3Photo = cell.viewWithTag(30) as! UIImageView
        let participant3Name = cell.viewWithTag(31) as! UILabel
        
        let participant4Stack = cell.viewWithTag(4)
        let participant4Photo = cell.viewWithTag(40) as! UIImageView
        let participant4Name = cell.viewWithTag(41) as! UILabel
        
        let participant5Stack = cell.viewWithTag(5)
        let participant5Photo = cell.viewWithTag(50) as! UIImageView
        let participant5Name = cell.viewWithTag(51) as! UILabel
        
        let participant6Stack = cell.viewWithTag(6)
        let participant6Photo = cell.viewWithTag(60) as! UIImageView
        let participant6Name = cell.viewWithTag(61) as! UILabel
        
        let participant7Stack = cell.viewWithTag(7)
        let participant7Photo = cell.viewWithTag(70) as! UIImageView
        let participant7Name = cell.viewWithTag(71) as! UILabel
        
        let participant8Stack = cell.viewWithTag(8)
        let participant8Photo = cell.viewWithTag(80) as! UIImageView
        let participant8Name = cell.viewWithTag(81) as! UILabel
        
        //set up stacks
        participant3Stack?.isHidden = true
        participant4Stack?.isHidden = true
        participant5Stack?.isHidden = true
        participant6Stack?.isHidden = true
        participant7Stack?.isHidden = true
        participant8Stack?.isHidden = true
        
        //MARK: participant1
        if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![0]) == true {
            participant1Accepted.image = UIImage(systemName: "person.fill.checkmark")
            participant1Accepted.tintColor = UIColor.systemGreen
        } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![0]) == true {
            participant1Accepted.image = UIImage(systemName: "person.fill.xmark")
            participant1Accepted.tintColor = UIColor.systemRed
        }
        if currUserID == challenges[indexPath.row].participants![0] {
            participant1Name.text = "You"
        } else {
            participant1Name.text = challenges[indexPath.row].senderUserName
        }
        UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].senderUserID! + challenges[indexPath.row].activity!)) { (userActivity) in
            participant1Average.text = String((userActivity?.averageScore)!)
            participant1Best.text = String((userActivity?.bestScore)!)
            if (userActivity?.played)! < 1 {
                participant1Win.text = "0%"
            } else {
                participant1Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
            }
        }
        
        //MARK: participant2
        if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![1]) == true {
            participant2Accepted.image = UIImage(systemName: "person.fill.checkmark")
            participant2Accepted.tintColor = UIColor.systemGreen
        } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![1]) == true {
            participant2Accepted.image = UIImage(systemName: "person.fill.xmark")
            participant2Accepted.tintColor = UIColor.systemRed
        }
        if currUserID == challenges[indexPath.row].participants![1] {
            participant2Name.text = "You"
        } else {
            participant2Name.text = challenges[indexPath.row].receiverUserName
        }
        UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].receiverUserID! + challenges[indexPath.row].activity!)) { (userActivity) in
            participant2Average.text = String((userActivity?.averageScore)!)
            participant2Best.text = String((userActivity?.bestScore)!)
            if (userActivity?.played)! < 1 {
                participant2Win.text = "0%"
            } else {
                participant2Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
            }
        }
        
        //MARK: participant3
        if challenges[indexPath.row].participants!.count > 2 {
            if currUserID == challenges[indexPath.row].participants![2] {
                participant3Name.text = "You"
            } else {
                UserService.getUserName(userID: challenges[indexPath.row].participants![2]) { (userNameData) in
                    participant3Name.text = userNameData
                }
            }
            if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![2]) == true {
                participant3Accepted.image = UIImage(systemName: "person.fill.checkmark")
                participant3Accepted.tintColor = UIColor.systemGreen
            } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![2]) == true {
                participant3Accepted.image = UIImage(systemName: "person.fill.xmark")
                participant3Accepted.tintColor = UIColor.systemRed
            }
            participant3Stack?.isHidden = false
            UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].participants![2] + challenges[indexPath.row].activity!)) { (userActivity) in
                participant3Average.text = String((userActivity?.averageScore)!)
                participant3Best.text = String((userActivity?.bestScore)!)
                if (userActivity?.played)! < 1 {
                    participant3Win.text = "0%"
                } else {
                    participant3Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
                }
            }
            
            //MARK: participant4
            if challenges[indexPath.row].participants!.count > 3 {
                if currUserID == challenges[indexPath.row].participants![3] {
                    participant4Name.text = "You"
                } else {
                    UserService.getUserName(userID: challenges[indexPath.row].participants![3]) { (userNameData) in
                        participant4Name.text = userNameData
                    }
                }
                if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![3]) == true {
                    participant4Accepted.image = UIImage(systemName: "person.fill.checkmark")
                    participant4Accepted.tintColor = UIColor.systemGreen
                } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![3]) == true {
                    participant4Accepted.image = UIImage(systemName: "person.fill.xmark")
                    participant4Accepted.tintColor = UIColor.systemRed
                }
                participant4Stack?.isHidden = false
                UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].participants![3] + challenges[indexPath.row].activity!)) { (userActivity) in
                    participant4Average.text = String((userActivity?.averageScore)!)
                    participant4Best.text = String((userActivity?.bestScore)!)
                    if (userActivity?.played)! < 1 {
                        participant4Win.text = "0%"
                    } else {
                        participant4Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
                    }
                }
                
                //MARK: participant5
                if challenges[indexPath.row].participants!.count > 4 {
                    if currUserID == challenges[indexPath.row].participants![4] {
                        participant5Name.text = "You"
                    } else {
                        UserService.getUserName(userID: challenges[indexPath.row].participants![4]) { (userNameData) in
                            participant5Name.text = userNameData
                        }
                    }
                    if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![4]) == true {
                        participant5Accepted.image = UIImage(systemName: "person.fill.checkmark")
                        participant5Accepted.tintColor = UIColor.systemGreen
                    } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![4]) == true {
                        participant5Accepted.image = UIImage(systemName: "person.fill.xmark")
                        participant5Accepted.tintColor = UIColor.systemRed
                    }
                    participant5Stack?.isHidden = false
                    UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].participants![4] + challenges[indexPath.row].activity!)) { (userActivity) in
                        participant5Average.text = String((userActivity?.averageScore)!)
                        participant5Best.text = String((userActivity?.bestScore)!)
                        if (userActivity?.played)! < 1 {
                            participant5Win.text = "0%"
                        } else {
                            participant5Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
                        }
                    }
                    
                    //MARK: participant6
                    if challenges[indexPath.row].participants!.count > 5 {
                        if currUserID == challenges[indexPath.row].participants![5] {
                            participant6Name.text = "You"
                        } else {
                            UserService.getUserName(userID: challenges[indexPath.row].participants![5]) { (userNameData) in
                                participant6Name.text = userNameData
                            }
                        }
                        if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![5]) == true {
                            participant6Accepted.image = UIImage(systemName: "person.fill.checkmark")
                            participant6Accepted.tintColor = UIColor.systemGreen
                        } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![5]) == true {
                            participant6Accepted.image = UIImage(systemName: "person.fill.xmark")
                            participant6Accepted.tintColor = UIColor.systemRed
                        }
                        participant6Stack?.isHidden = false
                        UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].participants![5] + challenges[indexPath.row].activity!)) { (userActivity) in
                            participant6Average.text = String((userActivity?.averageScore)!)
                            participant6Best.text = String((userActivity?.bestScore)!)
                            if (userActivity?.played)! < 1 {
                                participant6Win.text = "0%"
                            } else {
                                participant6Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
                            }
                        }
                        
                        //MARK: participant7
                        if challenges[indexPath.row].participants!.count > 6 {
                            if currUserID == challenges[indexPath.row].participants![6] {
                                participant7Name.text = "You"
                            } else {
                                UserService.getUserName(userID: challenges[indexPath.row].participants![6]) { (userNameData) in
                                    participant7Name.text = userNameData
                                }
                            }
                            if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![6]) == true {
                                participant7Accepted.image = UIImage(systemName: "person.fill.checkmark")
                                participant7Accepted.tintColor = UIColor.systemGreen
                            } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![6]) == true {
                                participant7Accepted.image = UIImage(systemName: "person.fill.xmark")
                                participant7Accepted.tintColor = UIColor.systemRed
                            }
                            participant7Stack?.isHidden = false
                            UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].participants![6] + challenges[indexPath.row].activity!)) { (userActivity) in
                                participant7Average.text = String((userActivity?.averageScore)!)
                                participant7Best.text = String((userActivity?.bestScore)!)
                                if (userActivity?.played)! < 1 {
                                    participant7Win.text = "0%"
                                } else {
                                    participant7Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
                                }
                            }
                            
                            //MARK: participant8
                            if challenges[indexPath.row].participants!.count > 7 {
                                if currUserID == challenges[indexPath.row].participants![7] {
                                    participant8Name.text = "You"
                                } else {
                                    UserService.getUserName(userID: challenges[indexPath.row].participants![7]) { (userNameData) in
                                        participant8Name.text = userNameData
                                    }
                                }
                                if challenges[indexPath.row].confirmed?.contains(challenges[indexPath.row].participants![7]) == true {
                                    participant8Accepted.image = UIImage(systemName: "person.fill.checkmark")
                                    participant8Accepted.tintColor = UIColor.systemGreen
                                } else if challenges[indexPath.row].denied?.contains(challenges[indexPath.row].participants![7]) == true {
                                    participant8Accepted.image = UIImage(systemName: "person.fill.xmark")
                                    participant8Accepted.tintColor = UIColor.systemRed
                                }
                                participant8Stack?.isHidden = false
                                UserActivityService.getUserActivity(userActivityID: String(challenges[indexPath.row].participants![7] + challenges[indexPath.row].activity!)) { (userActivity) in
                                    participant8Average.text = String((userActivity?.averageScore)!)
                                    participant8Best.text = String((userActivity?.bestScore)!)
                                    if (userActivity?.played)! < 1 {
                                        participant8Win.text = "0%"
                                    } else {
                                        participant8Win.text = String("\((((userActivity?.wins)! / (userActivity?.played)!) * 1000).rounded() / 10)%")
                                    }
                                }
                            }
                            return cell
                        }

Solution

  • The problem was that subviews within the TableView cell were being resized by the system.

    The solution was to set hugging priorities and compression resistance priorities on each of the stack views that were affected. This prevented any system resizing that was occurring.