I am fairly new to swift and Xcode and I am trying to make a tic tac toe game. I have everything figured out except how to draw a line through the three x\'s or o\'s. I have
Drawing in Swift 4.1
override func viewDidLoad() {
super.viewDidLoad()
self.lastPoint = CGPoint.zero
self.red = 0.0
self.green = 0.0
self.blue = 0.0
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK: Touch events
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
isSwiping = false
if let touch = touches.first{
lastPoint = touch.location(in: mainImageView)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
isSwiping = true;
if let touch = touches.first{
let currentPoint = touch.location(in: mainImageView)
UIGraphicsBeginImageContext(self.tempImageView.frame.size)
self.tempImageView.image?.draw(in: CGRect(x:0, y:0,width:self.tempImageView.frame.size.width, height:self.tempImageView.frame.size.height))
UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: currentPoint.x, y: currentPoint.y))
UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round)
UIGraphicsGetCurrentContext()?.setLineWidth(9.0)
UIGraphicsGetCurrentContext()?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
UIGraphicsGetCurrentContext()?.strokePath()
self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
lastPoint = currentPoint
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if(!isSwiping) {
// This is a single touch, draw a point
UIGraphicsBeginImageContext(self.tempImageView.frame.size)
self.tempImageView.image?.draw(in: CGRect(x:0, y:0,width:self.tempImageView.frame.size.width, height:self.tempImageView.frame.size.height))
UIGraphicsGetCurrentContext()?.setLineCap(CGLineCap.round)
UIGraphicsGetCurrentContext()?.setLineWidth(9.0)
UIGraphicsGetCurrentContext()?.move(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
UIGraphicsGetCurrentContext()?.addLine(to: CGPoint(x: lastPoint.x, y: lastPoint.y))
UIGraphicsGetCurrentContext()?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
UIGraphicsGetCurrentContext()?.strokePath()
self.tempImageView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
}
Try looking into UIBezierPath, it will help you a lot for drawing lines. Here is documentation. Here is an example:
override func drawRect(rect: CGRect) {
let aPath = UIBezierPath()
aPath.move(to: CGPoint(x:<#start x#>, y:<#start y#>))
aPath.addLine(to: CGPoint(x: <#end x#>, y: <#end y#>))
// Keep using the method addLine until you get to the one where about to close the path
aPath.close()
// If you want to stroke it with a red color
UIColor.red.set()
aPath.lineWidth = <#line width#>
aPath.stroke()
}
Make sure you put this code in the drawRect
, like in the example above.
If you need to update the drawing just call setNeedsDisplay()
to update.
Are you using SpriteKit? If not, you really should do for any kind of iOS games as it makes manipulating and adding sprites (images) and other game-style objects very easy.
Although not at all the best way in terms of coding best-practices, a very simple way to accomplish this would be to create a new view when someone wins, check which direction (out of the possible 8) the row is and then set the image of this view accordingly. The images would be semi-transparent (e.g. PNGs) squares each containing a different possible line.
If you want to do it the proper way research how to draw paths in SpriteKit between coordinates.
Hope this is of some help! Steve
Swift 3.1, inside a UIView:
public override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
context!.setLineWidth(2.0)
context!.setStrokeColor(UIColor.red.cgColor)
context?.move(to: CGPoint(x: 0, y: self.frame.size.height))
context?.addLine(to: CGPoint(x: self.frame.size.width, y: 0))
context!.strokePath()
}
If you want to add a line to a UIViewController, just add a UIView with this function as a subview to the UIViewController, ei:
let line = LineView(CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
self.view.addSubview(line)
In general, you have to draw a path in Core Graphics. You can follow this example:
let context = UIGraphicsGetCurrentContext()
CGContextSetLineWidth(context, 2.0)
CGContextSetStrokeColorWithColor(context, color)
CGContextMoveToPoint(context, startPoint)
CGContextAddLineToPoint(context, endPoint)
CGContextStrokePath(context)
Update for Swift 3.x using Epic Defeater's example
override func draw(_ rect: CGRect) {
let aPath = UIBezierPath()
aPath.move(to: CGPoint(x:20, y:50))
aPath.addLine(to: CGPoint(x:300, y:50))
//Keep using the method addLineToPoint until you get to the one where about to close the path
aPath.close()
//If you want to stroke it with a red color
UIColor.red.set()
aPath.stroke()
//If you want to fill it as well
aPath.fill()
}