I have been trying to add a background around my SKLabelNode, but I can't figure out how to do it programmatically in swift 3. I see some old posts that use .background, but that doesn't work for me.
let background = SKSpriteNode(color: UIColor.white, size: CGSize(width: CGFloat((title.frame.size.width)), height:CGFloat((title.frame.size.height))))
background.zPosition = -1
background.position = CGPoint(x: self.frame.width / 12 * 6, y: self.frame.height / 12 * 11); title.addChild(background)
Check this new code, I think this suited more to your problem
let shape = SKShapeNode()
shape.path = UIBezierPath(roundedRect: CGRect(x:(label?.frame.origin.x)! - 15, y: (label?.frame.origin.y)! - 15, width: ((label?.frame.size.width)!+30), height: ((label?.frame.size.height)! + 50 )), cornerRadius: 64).cgPath
shape.position = CGPoint(x: frame.midX, y: frame.midY)
shape.fillColor = UIColor.red
shape.strokeColor = UIColor.blue
shape.lineWidth = 5
label?.addChild(shape)
Related
In the following example I'm trying to insert a CATextLayer inside a UIBezierPath and rotate it -45 degrees.
class DiagonalView: UIView {
override func draw(_ rect: CGRect) {
let path = UIBezierPath()
path.move(to: .init(x: rect.maxX, y: rect.midY + (rect.midY / 2.5)))
path.addLine(to: .init(x: rect.midX + (rect.midX / 2.5), y: rect.maxY))
path.addLine(to: .init(x: rect.midX - (rect.midX / 10.5), y: rect.maxY))
path.addLine(to: .init(x: rect.maxX, y: rect.midY - (rect.midY / 10.5)))
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.fillColor = UIColor.black.cgColor
layer.addSublayer(shapeLayer)
let textlayer = CATextLayer.init()
textlayer.string = "iPhone X"
textlayer.fontSize = 12
textlayer.isWrapped = true
textlayer.foregroundColor = UIColor.white.cgColor
textlayer.frame = path.bounds
let degrees = -45.0
let radians = CGFloat(degrees * Double.pi / 180)
textlayer.transform = CATransform3DMakeTranslation(10, 50, 0)
textlayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.5, 1.0)
layer.addSublayer(textlayer)
}
}
let containerView = DiagonalView(frame: CGRect(x: 0.0, y: 0.0, width: 140.0, height: 140.0))
containerView.backgroundColor = .red
PlaygroundPage.current.liveView = containerView
Although its not actually the result that I expected
Result
Expected
Any idea of what mistake I might have done with the code?
Thanks a lot for your time!
Using this example I am trying to add a dashed border to my UITableView.
Trying to draw dashed border for UITableViewCell
But it does not work. It shows nothing.
func addDashedBottomBorder(to cell: UITableViewCell) {
let color = UIColor.black.cgColor
let shapeLayer:CAShapeLayer = CAShapeLayer()
let frameSize = cell.frame.size
let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: 0)
shapeLayer.bounds = shapeRect
shapeLayer.position = CGPoint(x: frameSize.width/2, y: frameSize.height)
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = color
shapeLayer.lineWidth = 2.0
shapeLayer.lineJoin = kCALineJoinRound
shapeLayer.lineDashPattern = [9,6]
shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: shapeRect.height, width: shapeRect.width, height: 0), cornerRadius: 0).cgPath
cell.layer.addSublayer(shapeLayer)
}
I am using this method in cellForRowAt but it shows me nothing and in viewDidLoad, table.separatorStyle = .none.
From the below 2 lines of your code:
shapeLayer.lineJoin = kCALineJoinRound
shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: shapeRect.height, width: shapeRect.width, height: 0), cornerRadius: 0).cgPath
kCALineJoinRound is making upper and lower dash lines but they are overlapping due to the height of UIBezierPath is 0. So, Updated your code as:
shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: shapeRect.height, width: shapeRect.width, height: 1), cornerRadius: 0).cgPath
It will hide the lower line and you will get the desired result.
Best Solution:
Rather than hiding lower dash line, you can correct it by providing just lineDashPhase to your CAShapeLayer, as:
shapeLayer.lineJoin = kCALineJoinRound
shapeLayer.lineDashPhase = 3.0 // Add "lineDashPhase" property to CAShapeLayer
shapeLayer.lineDashPattern = [9,6]
shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: shapeRect.height, width: shapeRect.width, height: 0), cornerRadius: 0).cgPath
Received line is:
All of the explanations I've found seem to say the same thing. I can't figure out why this isn't working.
var linePath = UIBezierPath()
linePath.move(to: CGPoint(x: 50, y: 50))
linePath.addLine(to: CGPoint(x: 100, y: 100))
var pattern : [CGFloat] = [10.0, 10.0]
linePath.setLineDash(pattern, count: pattern.count, phase: 0)
linePath.lineWidth = 10
linePath.lineCapStyle = .round
let shape = SKShapeNode()
shape.path = linePath.cgPath
shape.strokeColor = UIColor.white
self.addChild(shape)
This code successfully draws a line but shape does not inherit the dashed properties of linePath, including even the width. Any ideas?
let linePath = UIBezierPath()
linePath.move(to: CGPoint(x: 50, y: 50))
linePath.addLine(to: CGPoint(x: 100, y: 100))
var pattern: [CGFloat] = [10.0, 10.0]
let dashed = CGPathCreateCopyByDashingPath (linePath.CGPath, nil, 0, pattern, 2)
var shape = SKShapeNode(path: dashed)
shape.strokeColor = UIColor.white
self.addChild(shape)
NOTE: In Swift 3 CGPathCreateCopyByDashingPath has been replaced by path.copy(dashingWithPhase:lengths:)
e.g.
let dashed = SKShapeNode(path: linePath.cgPath.copy(dashingWithPhase: 2, lengths: pattern))
I have a SKShapeNode that I want to add a SKPhysicsBody to. Here's the code for the SKShapeNode:
let width: CGFloat = 200//self.frame.width
let height: CGFloat = self.frame.height
rightBlocker.path = UIBezierPath(roundedRect: CGRect(x:-width/2, y: -height/2, width: width, height: height), cornerRadius: 50).cgPath
rightBlocker.position = CGPoint(x: -75, y: self.frame.height / 2)
rightBlocker.fillColor = UIColor.white
rightBlocker.strokeColor = UIColor.white
rightBlocker.lineWidth = 10
rightBlocker.physicsBody?.affectedByGravity = false
rightBlocker.physicsBody?.isDynamic = false
addChild(rightBlocker)
I've tried to add a SKPhysicsBody using this line of code:
rightBlocker.physicsBody = SKPhysicsBody(rectangleOf: (rightBlocker.frame.size))
but whenever I do, it completely disappears. What am I doing wrong?
I want to hav this kind of animation in my app, a case where an arrow shape such that when clicked it transforms into a mark.
This is what i have at present using the code below
func handleTransform(){
let arrowPath = UIBezierPath()
arrowPath.move(to: CGPoint(x: 50, y: 0))
arrowPath.addLine(to: CGPoint(x: 25, y: 75))
arrowPath.addLine(to: CGPoint(x: 25, y: 75))
arrowPath.addLine(to: CGPoint(x: 25, y: 45))
arrowPath.addLine(to: CGPoint(x: 25, y: 35))
arrowPath.close()
let progressLines = CAShapeLayer()
progressLines.path = arrowPath.cgPath
progressLines.strokeColor = UIColor.black.cgColor
progressLines.fillColor = UIColor.clear.cgColor
progressLines.lineWidth = 10.0
progressLines.lineCap = kCALineCapRound
self.view.layer.addSublayer(progressLines)
let animateStrokeEnd = CABasicAnimation(keyPath: "strokeEnd")
animateStrokeEnd.duration = 3.0
animateStrokeEnd.fromValue = 0.0
animateStrokeEnd.toValue = 1.0
progressLines.add(animateStrokeEnd, forKey: "animate stroke end animation")
}
the flow is illustrated in the images bellow
On click of this image
It transform to this image
I have been able t solve, i did a switch image with animation