0

Currently I am using UICollectionView to make a grid of items. I want to draw grid lines as in the screenshot that works on both iPhones and iPads.

On iPad, either the label or the grid line is not correctly placed. On iPhone, the adjustments worked fine.

override func viewDidLoad() {
    self.automaticallyAdjustsScrollViewInsets = false
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .vertical
    layout.minimumLineSpacing = 1.0
    layout.minimumInteritemSpacing = 0.0
    collectionView.setCollectionViewLayout(layout, animated: false)
    collectionView.layoutIfNeeded()
    collectionView.contentOffset = CGPoint.zero
}
private let foundationScreenElems = ["ABOUT US", "CHAIRMAN'S MESSAGE", "MESSAGE OF CEO", "OUR GOALS", "PILLARS", "VISION AND MISSION", "QUALITY POLICY", "TERMS & CONDITIONS"]
var foundationGridLayers: [CALayer] = []

func drawHorizontalLines(rowsCount: Int) {
    var pos = UIDevice.current.userInterfaceIdiom == .pad ? collectionView.frame.width / 3.5 - 0.5 : collectionView.frame.width / 2.5 - 0.5
    var i = 1
    while i < rowsCount {
        if (viewId == .foundation && foundationGridLayers.count < 4) {
            let layer = CALayer()
            if (i == 3 && UIDevice.current.userInterfaceIdiom == .pad) {
                pos = pos + 10
            }
            layer.frame = CGRect(x: 10, y: CGFloat(i) * pos, width: self.view.frame.width - 20, height: 1.0)
            layer.backgroundColor = gridColor
            foundationGridLayers.append(layer)
            collectionView.layer.addSublayer(layer)
        }
        i += 1
    }
}

func drawVerticalLine(rowsCount: Int) {
    let top = getTop()
    let pos = UIDevice.current.userInterfaceIdiom == .pad ? collectionView.frame.width / 3.5 - 0.5 : collectionView.frame.width / 2.5 - 0.5
    let width = self.view.frame.width / 2
    let layer = CALayer()
    if (UIDevice.current.userInterfaceIdiom == .pad) {
        layer.frame = CGRect(x: width, y: top + 10, width: 1.0, height: pos * CGFloat(rowsCount) + 30)
    } else {
        layer.frame = CGRect(x: width, y: top - 10, width: 1.0, height: pos * CGFloat(rowsCount) - 10)
    }

    layer.backgroundColor = gridColor
    collectionView.layer.addSublayer(layer)
}

func getTop() -> CGFloat {
    let pos = UIDevice.current.userInterfaceIdiom == .pad ? collectionView.frame.width / 3 - 0.5 : collectionView.frame.width / 2.5 - 0.5
    let height = collectionView.frame.height
    let rowCount: CGFloat = CGFloat(foundationScreenElems.count / 2)
    let emptySpace = height - (pos * rowCount)
    return UIDevice.current.userInterfaceIdiom == .pad ? emptySpace / 2  : emptySpace / 4
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    let top = getTop()
    return UIEdgeInsets(top: top, left: 0, bottom: 10, right: 0)
}
extension GridViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let width = collectionView.frame.width / 2 - 0.5
        let height = UIDevice.current.userInterfaceIdiom == .pad ? collectionView.frame.width / 3 - 0.5 : collectionView.frame.width / 2.5 - 0.5
        return CGSize(width: width, height: height)
    }
}

On iPad, the Pillars rows is not aligned properly or the grid line is not at right position, but it works fine on iPhone.

ipad

iphone

Is there a way to draw grid lines independent of devices?

John Doe
  • 2,225
  • 6
  • 16
  • 44

1 Answers1

1

You can try creating 2 different types of custom cell, One for left and one for right with labels filled with border color to look.

You can have a look at this sample

iphone 8 plus enter image description here

In the collection view controller you can check for the cell and create the appropriate cell.

 override func collectionView(
        _ collectionView: UICollectionView,
        cellForItemAt indexPath: IndexPath
        ) -> UICollectionViewCell {

        var reuseIdentifier :String = "leftCell"

        let  itemsPerRow = 2;
        let column = indexPath.item % itemsPerRow;

        if(column == 1)
        {
            reuseIdentifier = "rightCell"
        }
        let cell = collectionView
            .dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)

        // Configure the cell
        return cell
    }

Make the cell fit any device screen

  func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.width/2, height: UIScreen.main.bounds.width/3);
    }

Add appropriate constraints so that the border labels always maintain a zero margin to the right

Pooja Kamath
  • 1,290
  • 1
  • 10
  • 17