user4806509 user4806509 - 3 months ago 43
iOS Question

How to fill a UIView with an alternating stripe pattern programmatically using Swift?

I can achieve an alternating stripe pattern fill using an image with

UIColor(patternImage: UIImage(named: "pattern.png"))
.

However, how can I achieve an alternating stripe pattern fill drawing it programmatically with some simple compact code?

Here are two examples I'd like to achieve.

Question


Using code, how do I fill a
UIView
with different alternating color stripes using Swift?


(1) a two color alternating pattern running top to bottom (90
degrees)?

(2) a three color alternating pattern running top left to bottom right
(45 degrees)?


enter image description here

Answer

Filling a view with a stripe pattern with two, three or more color stripes with adjustable stripe widths and rotation can be achieved with the below code. This code gives a three colour stripe pattern shown in the example image below.

Steps:

  1. Add the below code to ViewController.swift
  2. Add a UIView to Storyboard.
  3. Add new alignment contstraints to the UIView on the Storyboard; Horizontally in Container = 0, Vertically in Container = 0.
  4. In the Identity Inspector, set the UIView custom class to 'colorStripesView'.
  5. Connect the UIView on the Storyboard to the viewPattern IBOutlet in the code.

Code:

    ////   ViewController.swift

    //// 1. Add the below code to ViewController.swift
    //// 2. Add a UIView to Storyboard.
    //// 3. Add new alignment contstraints to the UIView on the Storyboard; Horizontally in Container = 0, Vertically in Container = 0.
    //// 4. In the Identity Inspector, set the UIView custom class to 'colorStripesView'.
    //// 5. Connect the UIView on the Storyboard to the viewPattern IBOutlet in the code.

    import UIKit

    class ViewController: UIViewController {
        @IBOutlet weak var viewPattern: UIView!

        override func viewDidLoad() {
            super.viewDidLoad()

            //// Extend width and height constraints by factor of 2 for viewPattern rotation.
            let widthConstraint = NSLayoutConstraint(item: viewPattern, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: (max(view.bounds.height, view.bounds.width)*2))
            viewPattern.addConstraint(widthConstraint)
            let heightConstraint = NSLayoutConstraint(item: viewPattern, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: (max(view.bounds.height, view.bounds.width)*2))
            viewPattern.addConstraint(heightConstraint)

            //// Rotate pattern 0 degrees - vertical.
            //viewPattern.transform = CGAffineTransformMakeRotation(CGFloat(M_PI*0/180))
            //// Rotate pattern 45 degrees - diagonal top right to bottom left.
            //viewPattern.transform = CGAffineTransformMakeRotation(CGFloat(M_PI*45/180))
            //// Rotate pattern 90 degrees - horizontal.
            //viewPattern.transform = CGAffineTransformMakeRotation(CGFloat(M_PI*90/180))
            //// Rotate pattern 135 degrees - diagonal top left to bottom right.
            viewPattern.transform = CGAffineTransformMakeRotation(CGFloat(M_PI*135/180))

            //// Set view color
            viewPattern.backgroundColor = UIColor.clearColor()
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    }

    class colorStripesView: UIView {
        override func drawRect(rect: CGRect) {
            //// Set pattern tile colors width and height; adjust the color width to adjust pattern.
            let color1 = UIColor(red: 255/255, green: 255/255, blue: 10/255, alpha: 1.0)
            let color1Width: CGFloat = 10
            let color1Height: CGFloat = 10

            let color2 = UIColor(red: 0/255, green: 0/255, blue: 254/255, alpha: 1.0)
            let color2Width: CGFloat = 10
            let color2Height: CGFloat = 10

            let color3 = UIColor(red: 0/255, green: 128/255, blue: 128/255, alpha: 1.0)
            let color3Width: CGFloat = 10
            let color3Height: CGFloat = 10

            //// Set pattern tile orientation vertical.
            let patternWidth: CGFloat = (color1Width + color2Width + color3Width)
            let patternHeight: CGFloat = min(color1Height, color2Height, color3Height)

            //// Set pattern tile size.
            let patternSize = CGSize(width: patternWidth, height: patternHeight)

            //// Draw pattern tile
            let context = UIGraphicsGetCurrentContext()
            UIGraphicsBeginImageContextWithOptions(patternSize, false, 0.0)

            let color1Path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: color1Width, height: color1Height))
            color1.setFill()
            color1Path.fill()

            let color2Path = UIBezierPath(rect: CGRect(x: color1Width, y: 0, width: color2Width, height: color2Height))
            color2.setFill()
            color2Path.fill()

            let color3Path = UIBezierPath(rect: CGRect(x: color1Width + color2Width, y: 0, width: color3Width, height: color3Height))
            color3.setFill()
            color3Path.fill()

            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

            //// Draw pattern in view
            UIColor(patternImage: image).setFill()
            CGContextFillRect(context, rect)
        }
    }

Simulator:

enter image description here