I'm writing a score keeping app for a game and I'd like the players to be able to record multiple stats for games that could have 4, 6, 8 or even more players. I set up my labels as shown below:
var playerOneReboundMadeLabel = UILabel()
var playerTwoReboundMadeLabel = UILabel()
var playerThreeReboundMadeLabel = UILabel()
var playerFourReboundMadeLabel = UILabel()
var playerFiveReboundMadeLabel = UILabel()
var playerSixReboundMadeLabel = UILabel()
var playerOneScoreLabel = UILabel()
var playerTwoScoreLabel = UILabel()
var playerThreeScoreLabel = UILabel()
var playerFourScoreLabel = UILabel()
var playerFiveScoreLabel = UILabel()
var playerSixScoreLabel = UILabel()
var numberOfPlayers = 6
override func viewDidLoad() {
var playerReboundAttemptLabelArray = [playerOneReboundAttemptsLabel, playerTwoReboundAttemptsLabel, playerThreeReboundAttemptsLabel, playerFourReboundAttemptsLabel, playerFiveReboundAttemptsLabel, playerSixReboundAttemptsLabel]
for player in 1...numberOfPlayers {
let label = UILabel(frame: CGRect(x: playerOneScoreLabel.frame.maxX, y: playerScoreLabelArray[player-1].frame.minY, width: viewWidth*columnThreeWidth, height: viewHeight*labelHeight))
label.tag = player 100
label.backgroundColor = UIColor(red: 255/255, green: 197/255, blue: 142/255, alpha: 1.0)
label.textAlignment = .center
label.font = UIFont(name: "AmericanTypewriter-Bold", size: 23)
label.text = "\(playerReboundAttemptsArray[player-1])"
label.adjustsFontSizeToFitWidth = true
label.isUserInteractionEnabled = true
playerStatsView.addSubview(label)
playerReboundAttemptLabelArray[player-1] = view.viewWithTag(player 100) as! UILabel
}
//playerThreeReboundAttemptsLabel = view.viewWithTag(106) as! UILabel
playerThreeReboundAttemptsLabel.text = "54"
}
When the "playerThreeReboundAttemptsLabel = view.viewWithTag(106) as! UILabel" is commented out the label doesn't change to "54" but when I activate it then it works. I think it may be due to creating a copy of the value in the array, but I don't fully understand it.
I feel like there should be a more Swifty way of doing this, although the above will work by assigning each of the labels outside of the for loop I was hoping someone could help with an more elegant and brief way of creating these that will allow me to do it dynamically by just changing the number of players variable before loading the view.
Thanks!
CodePudding user response:
Eliminate all of the discrete label properties. Just have two label arrays. Then your code becomes something like this:
var playerReboundLabels = [UILabel]()
var playerScoreLabels = [UILabel]()
var numberOfPlayers = 6
override func viewDidLoad() {
super.viewDidLoad()
// Create the rebound labels. Do something similar for the score labels
for player in 0..<numberOfPlayers {
let label = UILabel()
label.backgroundColor = UIColor(red: 255/255, green: 197/255, blue: 142/255, alpha: 1.0)
label.textAlignment = .center
label.font = UIFont(name: "AmericanTypewriter-Bold", size: 23)
label.text = "\(playerReboundAttemptsArray[player])"
label.adjustsFontSizeToFitWidth = true
label.isUserInteractionEnabled = true
playerStatsView.addSubview(label)
playerReboundLabels.append(label)
}
// Access a label via index, for example:
playerReboundLabels[3].text = "54"
}
Look into using UIStackView
or constraints to arrange the labels. Much better than trying to assign frames to each label.