Reputation: 3387
I am trying to dynamically arrange set of image data in an array on a UIView
I want four per role and max role is 12 making 4 per role. This is the problem, I can I split the array and place the images evenly where each and everyone should be. Eg:
12 Images
======|=====|======|======|
| | | |
| | | |
======|=====|======|======|
| | | |
| | | |
======|=====|======|======|
| | | |
| | | |
|=====|=====|======|======|
I know how to arrange the image, but then splitting the array is the problem. What if I have 7 images in the array that would be 4 at the top, 3 at the bottom or 10, which would be 4,4,2. I don't know how to go about it. That's why I don't have any code pasted at all. Any help on splitting and arranging the array would be appreciated. Thanks
Upvotes: 1
Views: 162
Reputation: 3387
So, this is what I did. I wrote a function that extends Array to split my Array evenly
extension Array {
func splitBy(subSize: Int) -> [[Element]] {
return 0.stride(to: self.count, by: subSize).map { startIndex in
let endIndex = startIndex.advancedBy(subSize, limit: self.count)
return Array(self[startIndex ..< endIndex])
}
}
}
Then, I did the bit of displaying the images with this
private func setGridView(gridCell: ProfileGrid, indexPath: NSIndexPath) {//140813008
let (location, photoCount, images) = dummyGrid[indexPath.row]
gridCell.imageCount.text = photoCount
gridCell.location.text = location
if images.count > 0 && images.count <= 4 {
for index in 0..<images.count {
let dedicatedWidth = self.view.frame.size.width/4 - 8
let imageView = UIImageView(frame: CGRect(x: (dedicatedWidth + 2) * CGFloat(index), y: 0, width: CGFloat(dedicatedWidth - 2), height: 80))
imageView.image = UIImage(named: images[index])
imageView.layer.cornerRadius = 5
imageView.clipsToBounds = true
gridCell.imageHolder.addSubview(imageView)
}
} else if images.count > 4 && images.count <= 8 {
let split = images.splitBy(4)
let firstSplit = split[0]
let secondSplit = split[1]
for index in 0..<firstSplit.count {
let dedicatedWidth = self.view.frame.size.width/4 - 8
let imageView = UIImageView(frame: CGRect(x: (dedicatedWidth + 2) * CGFloat(index), y: 0, width: CGFloat(dedicatedWidth - 2), height: 80))
imageView.image = UIImage(named: firstSplit[index])
imageView.layer.cornerRadius = 5
imageView.clipsToBounds = true
gridCell.imageHolder.addSubview(imageView)
}
for jDex in 0..<secondSplit.count {
let dedicatedWidth = self.view.frame.size.width/4 - 8
let imageView = UIImageView(frame: CGRect(x: (dedicatedWidth + 2) * CGFloat(jDex), y: 82, width: CGFloat(dedicatedWidth - 2), height: 80))
imageView.image = UIImage(named: secondSplit[jDex])
imageView.layer.cornerRadius = 5
imageView.clipsToBounds = true
gridCell.imageHolder.addSubview(imageView)
}
} else if images.count > 8 {
let split = images.splitBy(4)
let firstSplit = split[0]
let secondSplit = split[1]
let thirdSplit = split[2]
for index in 0..<firstSplit.count {
let dedicatedWidth = self.view.frame.size.width/4 - 8
let imageView = UIImageView(frame: CGRect(x: (dedicatedWidth + 2) * CGFloat(index), y: 0, width: CGFloat(dedicatedWidth - 2), height: 80))
imageView.image = UIImage(named: firstSplit[index])
imageView.layer.cornerRadius = 5
imageView.clipsToBounds = true
gridCell.imageHolder.addSubview(imageView)
}
for jDex in 0..<secondSplit.count {
let dedicatedWidth = self.view.frame.size.width/4 - 8
let imageView = UIImageView(frame: CGRect(x: (dedicatedWidth + 2) * CGFloat(jDex), y: 82, width: CGFloat(dedicatedWidth - 2), height: 80))
imageView.image = UIImage(named: secondSplit[jDex])
imageView.layer.cornerRadius = 5
imageView.clipsToBounds = true
gridCell.imageHolder.addSubview(imageView)
}
for tDex in 0..<thirdSplit.count {
let dedicatedWidth = self.view.frame.size.width/4 - 8
let imageView = UIImageView(frame: CGRect(x: (dedicatedWidth + 2) * CGFloat(tDex), y: 164, width: CGFloat(dedicatedWidth - 2), height: 80))
imageView.image = UIImage(named: thirdSplit[tDex])
imageView.layer.cornerRadius = 5
imageView.clipsToBounds = true
gridCell.imageHolder.addSubview(imageView)
}
}
}
If you've a better of doing it, I don't mind. My code is too big and kinda not professional from my on look of it. Ideas please
Upvotes: 0
Reputation: 503
Storing values in a single array and using the array as a data source for a 2D structure is fairly common. You can get the X and Y positions based on the index of the item and the width and height of the structure.
// number of images across the view
let width = 4;
// number of images down the view
let height = 3;
// index of the image in the array
let index = 10;
// index of the space from the left
// starting with 0
let xLocation = index % width; // 2
// index of the space from the top
// starting with 0
let yLocation = index / width; // 2
A function that returns the values as a tuple is below. All that you'd need to do is iterate over your array and it will return the positions of the items based on the provided information.
func getPosition(width:Int, index:Int) -> (Int,Int) {
return (index % width, index / width);
}
edit: code clarification
Upvotes: 1