How do I make shape rotate on its axis? - ios

The hexagon rotates, but it wont stay in place and rotate. What do I need to change in order for it to spin clockwise once every single time the button is clicked.
shape6 = CAShapeLayer()
view.layer.addSublayer(shape6)
shape6.opacity = 0.5
shape6.lineWidth = 2
shape6.lineJoin = kCALineJoinMiter
shape6.strokeColor = UIColor(hue: 0.786, saturation: 0.79, brightness: 0.53, alpha: 1.0).CGColor
shape6.fillColor = UIColor(hue: 0, saturation: 0, brightness: 0, alpha: 0).CGColor
path6 = UIBezierPath()
path6.moveToPoint(CGPointMake(35,430))
path6.addLineToPoint(CGPointMake(80, 300))
path6.closePath()
shape6.path = path6.CGPath
#IBAction func ispin(sender: AnyObject) {
UIView.animateWithDuration(1.0, animations: ({
self.shape1.transform = CATransform3DMakeRotation(30, 150, 400, 20)
self.shape2.transform = CATransform3DMakeRotation(30, 150, 400, 20)
self.shape3.transform = CATransform3DMakeRotation(30, 150, 400, 20)
self.shape4.transform = CATransform3DMakeRotation(30, 150, 400, 20)
self.shape5.transform = CATransform3DMakeRotation(30, 150, 400, 20)
self.shape6.transform = CATransform3DMakeRotation(30, 150, 400, 20)
}))
}

Try setting the anchor point of the shape shape6:
shape6.anchorPoint = CGPointMake(0.5, 0.5)

Related

UIButton shadow and lighting effect (Swift 4)

I'd like to add a lighting effect like these two buttons, a shadow on the bottom but also a lighted edge on top as if there were a light above it.
I've been experimenting with :
button.layer.shadowColor = UIColor.black.cgColor
button.layer.shadowColor.layer.shadowOffset = CGSize(width: 2, height: 2)
button.layer.shadowColor.layer.shadowRadius = 2
button.layer.shadowColor.layer.shadowOpacity = 8
button.layer.shadowColor.layer.masksToBounds = false
and get a nice shadow on the bottom, but how would I light up the top edge?
I was able to get a button pretty similar to your first drawing, just as an experiment:
The button background is constructed entirely using elementary drawing commands involving UIBezierPath and CGContext in a UIGraphicsImageRenderer. So if that's an acceptable sort of approach, you could just do a tweak on the sort of thing I'm doing.
let r = UIGraphicsImageRenderer(size: CGSize(width:100, height:100))
let im = r.image {
ctx in let con = ctx.cgContext
do {
let p = UIBezierPath(roundedRect: CGRect.init(x: 0, y: 0, width: 100, height: 50), cornerRadius: 10)
UIColor(white: 0.9, alpha: 1.0).setFill()
p.fill()
}
do {
let p = UIBezierPath(roundedRect: CGRect.init(x: 0, y: 50, width: 100, height: 50), cornerRadius: 10)
UIColor(white: 0.1, alpha: 1.0).setFill()
p.fill()
}
do {
let p = UIBezierPath(roundedRect: CGRect.init(x: 0, y: 2, width: 100, height: 95), cornerRadius: 10)
p.addClip()
}
let locs : [CGFloat] = [ 0.0, 0.2, 0.8, 1.0 ]
let colors : [CGFloat] = [
0.54, 0.54, 0.54, 1.0,
0.5, 0.5, 0.5, 1.0,
0.5, 0.5, 0.5, 1.0,
0.44, 0.44, 0.44, 1.0,
]
let sp = CGColorSpaceCreateDeviceRGB()
let grad = CGGradient(
colorSpace:sp, colorComponents: colors, locations: locs, count: 4)!
con.drawLinearGradient(grad,
start: CGPoint(x:0,y:0), end: CGPoint(x:0,y:100), options:[])
}
let b = UIButton(type: .custom)
b.setTitle("9", for: .normal)
b.setBackgroundImage(im, for: .normal)
b.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
b.titleLabel?.font = UIFont.systemFont(ofSize: 40, weight: .bold)
self.view.addSubview(b)
b.layer.borderWidth = 1
b.layer.borderColor = UIColor.black.cgColor
b.layer.cornerRadius = 10

Swift Animate lines with dots

I have created multiple circles (points) using CAShapeLayer and multiple lines connecting to those circles. Then i animate those circles. what i want to do is animate connected lines along with dots. But only circles are animating not the lines. How can i achieve this? is there a way to update lines position?`
`
var points: [CAShapeLayer] = []
let positions: [CGPoint] = [CGPoint(x: 70, y: 100),
CGPoint(x: 140, y: 100),
CGPoint(x: 210, y: 100),
CGPoint(x: 70, y: 200),
CGPoint(x: 140, y: 200),
CGPoint(x: 210, y: 200)]
var lines:[CAShapeLayer] = []
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
createPoints()
}
override func viewDidLoad() {
super.viewDidLoad()
}
func createPoints(){
for (index,position) in positions.enumerated() {
let point = CAShapeLayer()
point.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 10, height: 10), cornerRadius: 5).cgPath
point.frame = CGRect(x: position.x, y: position.y, width: 10, height: 10)
point.fillColor = UIColor.red.cgColor
points.append(point)
view.layer.addSublayer(points[index])
}
animatePosition(point: points[0])
drawLines()
}
func drawLines(){
for (index,_) in positions.enumerated() {
let path = UIBezierPath()
//Not completed
//set line's start position to dots position
path.move(to: points[index].position)
//set line's end position to dots position
path.addLine(to: points[index+1].position)
let line = CAShapeLayer()
line.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
line.strokeColor = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1).cgColor
line.lineWidth = 1
line.strokeStart = 0
line.path = path.cgPath
lines.append(line)
view.layer.addSublayer(line)
}
}
func animatePosition(point: CAShapeLayer) {
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = [10, 10 ]
animation.toValue = [100, 100]
animation.autoreverses = true
animation.repeatCount = .infinity
animation.isAdditive = true
point.add(animation, forKey: "pointStart")
// line.add(animation, forKey: "positionLine")
self.view.setNeedsLayout()
}
What i want is some thing like this:

render two UILabels in CGContext without overlapping

Hello i try to render two labels in one CGContext to get an UIImage - one above the other. However the code is ignoring the origins of the CGRects. Can anyone point me in the right direction?
// frames with positions and bounds
let frame = CGRect(x: 0, y: 0, width: 64, height: 64)
let upperFrame = CGRect(x: 0, y: 0, width: 64, height: 40)
let lowerFrame = CGRect(x: 0, y: 40, width: 64, height: 24)
// settings of lower label
let lowerLabel = UILabel(frame: lowerFrame)
lowerLabel.textAlignment = .center
lowerLabel.backgroundColor = UIColor.init(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.0)
lowerLabel.textColor = .black
lowerLabel.font = nameLabel.font.withSize(15.0)
lowerLabel.adjustsFontSizeToFitWidth = true
lowerLabel.minimumScaleFactor = 1.0/nameLabel.font.pointSize
lowerLabel.text = "Monatsende"
// settings of upper label
let upperLabel = UILabel(frame: upperFrame)
upperLabel.textAlignment = .center
upperLabel.backgroundColor = UIColor.init(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.0)
upperLabel.textColor = .black
upperLabel.font = upperLabel.font.withSize(15.0)
upperLabel.adjustsFontSizeToFitWidth = true
upperLabel.minimumScaleFactor = 1.0/upperLabel.font.pointSize
upperLabel.text = "2500 €"
// draw alltogether
UIGraphicsBeginImageContext(frame.size)
if let currentContext = UIGraphicsGetCurrentContext() {
lowerlabel.layer.render(in: currentContext)
upperLabel.layer.render(in: currentContext)
let image = UIGraphicsGetImageFromCurrentImageContext()
return image
}
the result is, that both labels are overlapping each other:
as i understand it the two labels should be clearly distinguishable from one another.

Add gradient layer to uiviewcontroller uiview

I am trying to create a simple gradient for the background of a UIViewController. My code is:
let gradientLayer = CAGradientLayer()
gradientLayer.frame = view.bounds
let bottomColor = UIColor(hue: 208 / 360, saturation: 82 / 100, brightness: 0.9, alpha: 1)
let topColor = UIColor(hue: 208 / 360, saturation: 41 / 100, brightness: 0.9, alpha: 1)
gradientLayer.colors = [bottomColor, topColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.1)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
view.layer.addSublayer(gradientLayer)
The gradient does not show. When I look in the view debugger, I do not see it. I check the frame of the view and it looks ok
x: 0, y:0, width: 375, height: 667
I've tried the view.layer.insert at method as well, but that did not work. If I do
view.layer.backgroundColor.orange
then I do see an orange background. Am I missing something?
Change
gradientLayer.colors = [bottomColor, topColor]
to
gradientLayer.colors = [bottomColor.cgColor, topColor.cgColor]

Move coordinates of UIView to LLO with Swift

I would expect this code to move my newLabel from the upper left corner (ULO) to the lower left corner (LLO) but it doesn't! Apparently I need someone to hold my hand through the process of setting (0, 0) to LLO for a UIView. I've been through the documentation and read post after post on this forum but can't seem to make it happen. Disclaimer: I am trying to accomplish this in a playground in xCode 6 beta 2 so it possible it's a bug or not supported.
var newLabel = UILabel(frame: CGRectMake(0, 0, 150, 50))
newLabel.text = "This is a test"
newLabel.layer.borderWidth = 2
newLabel.textAlignment = NSTextAlignment.Center
newLabel.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.8)
var myView = UIView(frame: CGRectMake(0, 0, 200, 100))
myView.layer.borderWidth = 2
myView.addSubview(newLabel)
myView.transform = CGAffineTransformMakeScale(1, -1)
myView.backgroundColor = UIColor(red: 0.8, green: 0, blue: 0, alpha: 0.8)
It seems like you haven't added Myview in main view try this code:--
var newLabel = UILabel(frame: CGRectMake(0, 0, 150, 50))
newLabel.text = "This is a test"
newLabel.layer.borderWidth = 2
newLabel.textAlignment = NSTextAlignment.Center
newLabel.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.8)
var myView = UIView(frame: CGRectMake(0, 0, 200, 100))
myView.layer.borderWidth = 2
myView.addSubview(newLabel)
myView.transform = CGAffineTransformMakeScale(1, -1)
myView.backgroundColor = UIColor(red: 0.8, green: 0, blue: 0, alpha: 0.8)
self.view.addSubview(myView);
To flip the UIView it has to be a subView of another view... My issue was I was trying to flip the mainView or baseView which apparently cant be done. This make since, since it needs a graphic space to be able to draw to. Below is the code achieving what I was looking for. Also of not I also had to "flip" my label as well to return it to it upright state (again this is logical).
var newLabel = UILabel(frame: CGRectMake(0, 0, 150, 50))
newLabel.transform = CGAffineTransformMakeScale(1, -1)
newLabel.text = "This is a test"
newLabel.layer.borderWidth = 2
newLabel.textAlignment = NSTextAlignment.Center
newLabel.backgroundColor = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.8)
var subView = UIView(frame: CGRectMake(50, 50, 200, 100))
subView.transform = CGAffineTransformMakeScale(1, -1)
subView.layer.borderWidth = 2
subView.addSubview(newLabel)
subView.backgroundColor = UIColor(red: 0.8, green: 0, blue: 0, alpha: 0.8)
var myView = UIView()
myView = UIView(frame: CGRectMake(0, 0, 300, 200))
//myView.transform = CGAffineTransformMakeScale(1, -1)
myView.layer.borderWidth = 2
myView.addSubview(subView)
myView.backgroundColor = UIColor(red: 0, green: 0.8, blue: 0, alpha: 0.8)
Thanks #Mohit for your input in helping me to find the solution.

Resources