Is it possible to customize the Navigation Bar to look like the picture below? Obviously that has a transparent background not a grey one.
I've tried:
UINavigationBar.appearance().setBackgroundImage(UIImage(named:"pattern.png"),
for: .default)
That seems to capture the colour but not the format of the navigation bar.
I am trying to avoid creating a custom nav bar with a UIView or anything like that because that would mean a lot of extra work for such a small change.My app has a lot of views using a Navigation Controller.
Thanks in advance.
Use this to add the zigzag pattern to your navigationBar (version2), or you can create a custom UIImage with your desired pattern (version1 (favorite))
Getting the image
import UIKit
extension UIImage {
static func pathZigZagForCGRect(rect: CGRect) ->UIBezierPath
{
let width = rect.size.width
let height = rect.size.height
let zigZagWidth = CGFloat(7)
let zigZagHeight = CGFloat(5)
var yInitial = height-zigZagHeight
var zigZagPath = UIBezierPath()
zigZagPath.move(to: CGPoint(x:0, y:0))
zigZagPath.addLine(to: CGPoint(x:0, y:yInitial))
var slope = -1
var x = CGFloat(0)
var i = 0
while x < width {
x = zigZagWidth * CGFloat(i)
let p = zigZagHeight * CGFloat(slope) - 5
let y = yInitial + p
let point = CGPoint(x: x, y: y)
zigZagPath.addLine(to: point)
slope = slope*(-1)
i += 1
}
zigZagPath.addLine(to: CGPoint(x:width,y: 0))
zigZagPath.addLine(to: CGPoint(x:0,y: 0))
zigZagPath.close()
return zigZagPath
}
static func zigZagImage(rect: CGRect,color:UIColor)->UIImage {
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
var ctx = UIGraphicsGetCurrentContext()!
ctx.clear(CGRect(x: 0, y: 0, width: rect.size.width, height: rect.size.height))
ctx.setFillColor(color.cgColor)
let path = UIImage.pathZigZagForCGRect(rect: rect)
ctx.addPath(path.cgPath)
ctx.fillPath()
//draw triangle
let img = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return img
}
}
Using it
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.navigationBar.setBackgroundImage( UIImage.zigZagImage(rect: CGRect(x: 0, y: 0, width: (self.navigationController?.navigationBar.frame.size.width)!, height: (self.navigationController?.navigationBar.frame.height)! + 20),color:UIColor.red).resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch), for: .default)
}
Result
func pathZigZagForView(givenView: UIView) ->UIBezierPath
{
let width = givenView.frame.size.width
let height = givenView.frame.size.height
let zigZagWidth = CGFloat(7)
let zigZagHeight = CGFloat(5)
var yInitial = height-zigZagHeight
var zigZagPath = UIBezierPath()
zigZagPath.move(to: CGPoint(x:0, y:0))
zigZagPath.addLine(to: CGPoint(x:0, y:yInitial))
var slope = -1
var x = CGFloat(0)
var i = 0
while x < width {
x = zigZagWidth * CGFloat(i)
let p = zigZagHeight * CGFloat(slope) - 5
let y = yInitial + p
let point = CGPoint(x: x, y: y)
zigZagPath.addLine(to: point)
slope = slope*(-1)
i += 1
}
zigZagPath.addLine(to: CGPoint(x:width,y: 0))
zigZagPath.addLine(to: CGPoint(x:0,y: 0))
zigZagPath.close()
return zigZagPath
}
func applyZigZagEffect(givenView: UIView) {
let shapeLayer = CAShapeLayer(layer: givenView.layer)
shapeLayer.path = self.pathZigZagForView(givenView: givenView).cgPath
shapeLayer.frame = givenView.bounds
shapeLayer.masksToBounds = true
givenView.layer.mask = shapeLayer
}
Using it
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.navigationController?.navigationBar.backgroundColor = UIColor.red
self.applyZigZagEffect(givenView: (self.navigationController?.navigationBar)!)
}
Hope this helps you