The task is to obtain an array containing a picture and a caption for it to display this data: two pictures, two more below them, etc. (in the attachment is a screenshot of the implementation).

In general - I wrote a working code, but I don’t like it - I place each picture and caption in UIView and ask UIView where to display on the screen. This works fine, if I have only 4 elements in the array, but if I want to process 100 elements, it’s pretty silly to prescribe the location of each UIView.

On CSS, I would place the containers in a row with float: right and after every second would just do a line break ...) But how to implement this on Swift?

let catalogList = ["1.jpg": "Стена", "2.jpg": "Микрофон", "3.jpg": "Инструменты", "4.jpg": "Концерт"] var currentItems = 0 override func viewDidLoad() { super.viewDidLoad() for i in catalogList { currentItems += 1 if currentItems <= 2 { if currentItems % 2 < 1 { addNew(pic: i.key, text: i.value, x: 30, y: 65) } else { addNew(pic: i.key, text: i.value, x: 220, y: 65) } } else { if currentItems % 2 < 1 { addNew(pic: i.key, text: i.value, x: 30, y: 300) } else { addNew(pic: i.key, text: i.value, x: 220, y: 300) } } } } func addNew(pic: String, text: String, x: Int, y: Int) { let viewThing = UIView(frame: CGRect(x: x, y: y, width: 165, height: 220)) self.view.addSubview(viewThing) let labelThing = UILabel(frame: CGRect(x: 5, y: 190, width: 165, height: 30)) labelThing.text = text viewThing.addSubview(labelThing) let imageThing = UIImageView(frame: CGRect(x: 0, y: 0, width: 165, height: 190)) imageThing.image = UIImage(named: pic) viewThing.addSubview(imageThing) } 

enter image description here

    1 answer 1

    Use a UICollectionView with the necessary FlowLayout . According to the screenshot, conventionally, for each cell, set the width to be 1/2 the width of the collection minus the padding between the cells and the height to be 3/2 the width of the cell:

     let itemsPerRow: CGFloat = 2 let sectionInsets = UIEdgeInsets(top: 50.0, left: 20.0, bottom: 50.0, right: 20.0) ... func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let paddingSpace = sectionInsets.left * (itemsPerRow + 1) let availableWidth = collectionView.bounds.width - paddingSpace let widthPerItem = availableWidth / itemsPerRow let heightPerItem = widthPerItem * 3 / 2 return CGSize(width: widthPerItem, height: heightPerItem) } 

    Documentation link

    Very detailed and detailed example on raywenderlich.com