Federica Benacquista
Federica Benacquista

Reputation: 843

How to shuffle an array of UIViews

I'm trying to build an app where I have 10 UIViews and when you press a button it randomly shows them one at a time. I created an Array of views (I don't know if I did that in the right way) and I'm trying to code the function to display them (randomly, one at a time). So right now I have the ten UIViews (I'm just putting one down here to show you but I have 10):

@IBOutlet weak var messageView: UIView! 
var messageArray = [UIView] ()
var currentVisibleMViews = 1

and inside viewDidLoad (obviously I still did this 10 times):

messageArray.append(messageView)

Now, I connected my button as well and I tried different things. Right now it's like this:

 @IBAction func addMessageViewButton(_ sender: Any) {
      if currentVisibleMViews > 9 {
        messageArray.forEach { (uiview) in
            uiview.isHidden = true
        }
        currentVisibleMViews = 0

    } else {
        messageArray[currentVisibleMViews].isHidden = false
        currentVisibleMViews += 1

   }

  }

This way, it shows the views one at a time in order, but when I have 10 it removes them all. Plus if I, for example, have 8 views, I close messageView6 and press again addMessageViewButton, it won't show me messageView6 but messageView9 (that's why I want them to be random).

I googled how to do what I want to and it says something like I should try the Fisher Yates Shuffle algorithm but I don't know how to do that because my array contains UIViews. Any solution?

Upvotes: 1

Views: 138

Answers (2)

Sulthan
Sulthan

Reputation: 130102

I would avoid keeping state that can be calculated easily because it will only complicate things for you:

@IBAction func addMessageViewButton(_ sender: Any) { 
    let hiddenViews = messageArray.filter { $0.isHidden }
    guard !hiddenViews.isEmpty else {
       // hide everything if nothing else to show
       messageArray.forEach { $0.isHidden = true }
       return
    }

    // show random view
    let randomHiddenView = hiddenViews.randomElement()
    randomHiddenView.isHidden = false
}

Upvotes: 2

ofundefined
ofundefined

Reputation: 3309

Have you heard of or tried using the native Swift method shufle()?

https://developer.apple.com/documentation/swift/array/2994753-shuffle

var names = [uviewC, uviewF, uviewE, uviewA, uviewD, uviewB]
names.shuffle(using:)

Would result something like, for instance:

[uviewD, uviewE, uviewB, uviewC, uviewF, uviewA]

Upvotes: 2

Related Questions