Grid View in iOS

How to implement Grid Layout for ios

I was able to implement GridLayout with help of the following blog article:
https://web.archive.org/web/20170620013903/http://blog.stablekernel.com/creating-a-custom-uicollectionviewlayout

In brief I had to implement my own UICollectionViewLayout, but I didn't need the complexity as it was presented in the article.

The problem with this solution is cell reusing, which I don't need and there is no way to switch it off.

Grid layout with CollectionView in Swift

Create the UICollectionViewController like this in a file that sub-classes from UICollectionViewController:

convenience override init() {
var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = CGSizeMake(<width>, <height>)
// Setting the space between cells
layout.minimumInteritemSpacing = <Space between columns>
layout.minimumLineSpacing = <Space between rows>
return (self.init(collectionViewLayout: layout))
}

In the viewDidLoad you an set the background color like this:

self.collectionView.backgroundColor = UIColor.orangeColor()

My guess is you can set a background image like this:

self.collectionView?.backgroundColor = UIColor(patternImage: UIImage(named: "image.png")!)

The blur effect that you found looks good. I am having trouble figuring out how it would work though. Probably set it using the backgroundView property.

I'll update if I find the answer.

Update:

Here is an idea of something that might work for blurring the cells.

Create a cocoa-touch class that sub-classes from UICollectionViewCell, then add this code to it:

convenience override init(frame: CGRect) {
self.init(frame: frame)
var blurEffect: UIVisualEffect
blurEffect = UIBlurEffect(style: .Light)
var visualEffectView: UIVisualEffectView
visualEffectView = UIVisualEffectView(effect: blurEffect)
visualEffectView.frame = self.maskView!.bounds
self.addSubview(visualEffectView)
}

override func layoutSubviews() {
super.layoutSubviews()
self.maskView!.frame = self.contentView.bounds
}

Then in the CollectionViewController file, in the viewDidLoad, change this line of code:

self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

Change UICollectionViewCell.self to <Name of CollectionViewCell file>.self

How to implement dynamic multi dimensional grid view(scroll view)?

use UICollectionView, you can get many examples here https://www.cocoacontrols.com/search?utf8=✓&q=grid

How to create 2 x 2 grid layout using Collection View?

First of all, get three variables together depending on your needs. Those are the minimum spacing (Both InteritemSpacing and Line spacing - Should be same UXwise but you can change that in delegate methods if you like. The interitem space however must always be equal to minimumSpacing), edgeInsetPadding and the number of items you want in a row.

private var numberOfItemsInRow = 2

private var minimumSpacing = 5

private var edgeInsetPadding = 10

In your code, you have already defined your Edge Insets as:

 UIEdgeInsets(
top: 5, left: 5, bottom: 5, right: 5
)

The left and right insets are important for correctly determining the size of the item. left+right gives us a grand sum of 10. This should be assigned to edgeInsetPadding like this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let inset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
edgeInsetPadding = inset.left+inset.right
return inset
}

Now lets get to your UICollectionViewDelegateFlowLayout. Update the following methods.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return minimumSpacing
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return minimumSpacing
}

Now lets get to the main part. Modify your sizeForItemAt in UICollectionViewDelegateFlowLayout as:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (Int(UIScreen.main.bounds.size.width) - (numberOfItemsInRow - 1) * minimumSpacing - edgeInsetPadding) / numberOfItemsInRow
return CGSize(width: width, height: width)
}

And this is it. You now get two equal size tiles in 2x2 grid. If you want to change this in future, just change the numberOfItemsInRow variable to something else. Like 3 for 3x3.

Drawing a grid on a UIView in Swift

Just Copy and paste the below code and you will be good to go. I haven't check your logic of drawing correct grid i have just solved the not drawing issue. If it draw wrong grid then i will re-check your grid logic for now it just help you to draw something using UIBezierPath

class GridView: UIView
{
private var path = UIBezierPath()
fileprivate var gridWidthMultiple: CGFloat
{
return 10
}
fileprivate var gridHeightMultiple : CGFloat
{
return 20
}

fileprivate var gridWidth: CGFloat
{
return bounds.width/CGFloat(gridWidthMultiple)
}

fileprivate var gridHeight: CGFloat
{
return bounds.height/CGFloat(gridHeightMultiple)
}

fileprivate var gridCenter: CGPoint {
return CGPoint(x: bounds.midX, y: bounds.midY)
}

fileprivate func drawGrid()
{
path = UIBezierPath()
path.lineWidth = 5.0

for index in 1...Int(gridWidthMultiple) - 1
{
let start = CGPoint(x: CGFloat(index) * gridWidth, y: 0)
let end = CGPoint(x: CGFloat(index) * gridWidth, y:bounds.height)
path.move(to: start)
path.addLine(to: end)
}

for index in 1...Int(gridHeightMultiple) - 1 {
let start = CGPoint(x: 0, y: CGFloat(index) * gridHeight)
let end = CGPoint(x: bounds.width, y: CGFloat(index) * gridHeight)
path.move(to: start)
path.addLine(to: end)
}

//Close the path.
path.close()

}

override func draw(_ rect: CGRect)
{
drawGrid()

// Specify a border (stroke) color.
UIColor.purple.setStroke()
path.stroke()
}
}


Related Topics



Leave a reply



Submit