I'm trying to give a UITableViewCell a 'waved' bottom to make it look like a 'ripped off paper' effect (for an order receipt). I want to draw this over the whole length of the cell.
I found this solution on StackOverflow, which creates one single sine between two points.
I tried altering that code to make the effect I need (I know there's a lot wrong in my code):
let path = UIBezierPath()
let origin = CGPoint(x: 0, y: bounds.size.height / 2)
path.move(to: origin)
let graphWidth: CGFloat = 0.8 // Graph is 80% of the width of the view
let amplitude: CGFloat = 0.5 // Amplitude of sine wave is 30% of view
for angle in stride(from: 1.0, through: bounds.size.width * 5.0, by: 1.0) {
let x = origin.x + CGFloat(angle/360.0) * bounds.size.width * (360 / (bounds.size.width * 10.0))
let y = origin.y - CGFloat(sin(angle/180.0 * CGFloat.pi)) * bounds.size.height * amplitude * (360 / (bounds.size.width * 10.0))
path.addLine(to: CGPoint(x: x, y: y))
}
What would be the best approach here? If I could get above solution working and looking like the image, that would be perfect. If anyone has other suggestions, I'm open to everything.
All credit to vacawama answer. You can achieve this as below,
class SineView: UIView {
let graphWidth: CGFloat = 0.15
let amplitude: CGFloat = 0.1
override func draw(_ rect: CGRect) {
let width = rect.width
let height = rect.height
let origin = CGPoint(x: 0, y: height * 0.50)
let path = UIBezierPath()
path.move(to: origin)
var endY: CGFloat = 0.0
let step = 5.0
for angle in stride(from: step, through: Double(width) * (step * step), by: step) {
let x = origin.x + CGFloat(angle/360.0) * width * graphWidth
let y = origin.y - CGFloat(sin(angle/180.0 * Double.pi)) * height * amplitude
path.addLine(to: CGPoint(x: x, y: y))
endY = y
}
path.addLine(to: CGPoint(x: width, y: endY))
path.addLine(to: CGPoint(x: width, y: height))
path.addLine(to: CGPoint(x: 0, y: height))
path.addLine(to: CGPoint(x: 0, y: origin.y))
UIColor.black.setFill()
path.fill()
UIColor.black.setStroke()
path.stroke()
}
}
Usage
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let size = view.frame.size
let sineView = SineView(frame: CGRect(x: 0, y: 100, width: size.width, height: 60))
sineView.backgroundColor = .white
self.view.addSubview(sineView)
}
}
Output
You can play with the graphWidth
and amplitude
to adjust the graph as you like.