CABasicAnimation in Swift Playground - animation

Been going nuts trying to get a live view of an animation in a Swift Playground like in the WWDC "Swift Playgrounds" video. I tried to do a UIView.animateWithDuration with no luck so I am now trying to do a CABasicaAnimation because this seems to be what was used in the demo. I'be gotten rid of a lot of confusing errors and have imported the proper frameworks but am still having no luck getting my little circle to do anything but sit still in the center of my XCPShowView. Here is my code:
import Foundation
import XCPlayground
import UIKit
import QuartzCore
//Circle Button
class timerButtonGraphics: UIView {
override func drawRect(rect: CGRect) {
let colorGreen = UIColor(red: 0.310, green: 0.725, blue: 0.624, alpha: 1.000)
let colorRed = UIColor(red: 241/255, green: 93/255, blue: 79/255, alpha: 100)
var bounds = self.bounds
var center = CGPoint()
center.x = bounds.origin.x + bounds.size.width / 2
center.y = bounds.origin.y + bounds.size.height / 2
var radius = 61
var path:UIBezierPath = UIBezierPath()
path.addArcWithCenter(center, radius: CGFloat(radius), startAngle: CGFloat(0.0), endAngle: CGFloat(Float(M_PI) * 2.0), clockwise: true)
path.strokeWithBlendMode(kCGBlendModeNormal, alpha: 100)
path.lineWidth = 5
colorGreen.setStroke()
path.stroke()
//Define the animation here
var anim = CABasicAnimation()
anim.keyPath = "scale.x"
anim.fromValue = 1
anim.toValue = 100
anim.delegate = self
self.layer.addAnimation(anim, forKey: nil)
}
}
var test = timerButtonGraphics(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
test.setTranslatesAutoresizingMaskIntoConstraints(true)
XCPShowView("Circle Animation", test)`

The first part of the solution is to enable the Run in Full Simulator option. See this answer for a step-by-step.
The second part of the solution is to contain your animated view in a container view, e.g.:
let container = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
XCPShowView("Circle Animation", container)
let test = timerButtonGraphics(frame: CGRect(x: 198, y: 0, width: 4, height: 400))
container.addSubview(test)
The third part of the solution is to correct your animation. The keyPath should be transform.scale.x instead of scale.x and you need to add a duration, e.g.:
anim.keyPath = "transform.scale.x"
anim.duration = 5
You should then be able to view the animation in your playground.

Related

How can I create multiple UISwitches from an array positioned one after another?

I have a popup view, that I would like to populate with ~15 UISwitches. Now it would be stupid to do all of that manually, so in Android I have set up a for loop to create said UISwitches from an array and you are able to toggle each one on and off and so on, each having their own value. I have created one switch, but when trying to create multiple from an array, none show up and I have no idea how I would be able to position them one after another.
let mySwitch = UISwitch()
mySwitch.isOn = false
mySwitch.center = self.view.center
mySwitch.thumbTintColor = UIColor(red: 23.0/255, green: 145.0/255, blue: 255.0/255, alpha: 1.0)
mySwitch.tintColor = UIColor(red: 23.0/255, green: 145.0/255, blue: 255.0/255, alpha: 1.0)
mySwitch.onTintColor = UIColor.black
mySwitch.backgroundColor = UIColor.white
self.view.addSubview(mySwitch)
var scrol = UIScrollView()
override func viewDidLoad() {
super.viewDidLoad()
scrol.frame = CGRect(x: 10, y: 0, width: self.view.frame.size.width, height: 200)
var yPos = 0.0
for i in 0...10 {
let mySwitch = UISwitch()
mySwitch.frame = CGRect(x: 10, y: yPos + 10, width: 50, height: 25)
mySwitch.isOn = false
// mySwitch.center = self.view.center
mySwitch.tag = i
mySwitch.thumbTintColor = UIColor(red: 23.0/255, green: 145.0/255, blue: 255.0/255, alpha: 1.0)
mySwitch.tintColor = UIColor(red: 23.0/255, green: 145.0/255, blue: 255.0/255, alpha: 1.0)
mySwitch.onTintColor = UIColor.black
mySwitch.backgroundColor = UIColor.white
yPos = Double(mySwitch.frame.origin.y + mySwitch.frame.size.height)
mySwitch.addTarget(self, action: #selector(onSwitchChange(_:)), for: .touchUpInside)
scrol.addSubview(mySwitch)
}
scrol.backgroundColor = .yellow
scrol.isScrollEnabled = true
self.view.addSubview(scrol)
}
func onSwitchChange(_ sender: UISwitch) {
print(" switch tapped \(sender.tag)")
}
Check out this, i have added a scrollView inside a UIView and have added multiple UISwitch as you have given in code with Frame set for UISwitch.
I'd recommend looking at UIStackView.
This allows you to easily add multiple UI elements to the screen at consistent positions without any hassle.
First you'd want to create a stack view:
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.spacing = 10
add it and constrain it:
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: view.topAnchor),
// etc, etc
])
Then you'd simply add a series of switches to the stack view:
for i in 0..<10 {
let switch = UISwitch()
// Configure switch
stackView.addArrangedSubview(switch)
}

animation not working in xcode 8 playground swift 3

I am trying to simply learn more about animations in Xcode 8 playground using swift 3. I have already learned that swift no longer uses XCPlayground, instead, using "import PlaygroundSupport".
I can not get anything to show in the Assistant Editor. Does anyone know the fix for this or is it just a bug with the new Xcode 8
Any help would be awesome. Thanks.
import UIKit
import PlaygroundSupport
let containerView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 375.0, height: 667.0))
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = containerView
let circle = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0))
circle.center = containerView.center
circle.layer.cornerRadius = 25.0
let startingColor = UIColor(red: (253.0/255.0), green: (159.0/255.0), blue: (47.0/255.0), alpha: 1.0)
circle.backgroundColor = startingColor
containerView.addSubview(circle);
let rectangle = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 50.0, height: 50.0))
rectangle.center = containerView.center
rectangle.layer.cornerRadius = 5.0
rectangle.backgroundColor = UIColor.white
containerView.addSubview(rectangle)
UIView.animate(withDuration: 2.0, animations: { () -> Void in
let endingColor = UIColor(red: (255.0/255.0), green: (61.0/255.0), blue: (24.0/255.0), alpha: 1.0)
circle.backgroundColor = endingColor
let scaleTransform = CGAffineTransform(scaleX: 5.0, y: 5.0)
circle.transform = scaleTransform
let rotationTransform = CGAffineTransform(rotationAngle: 3.14)
rectangle.transform = rotationTransform
})
Open the assistant editor to view the live view of the animation as mentioned in the article you're basing this off

Swift - Delete Animation Effects

I have an animation that deletes a circle in the UI and then recreates it somewhere else, but when I recreate it, it is smaller than what I want. I can't figure out why it is appearing smaller.
let viewsToAnimate = [circleFrame]
UIView.perform(UISystemAnimation.delete, on: viewsToAnimate, options: [], animations: {
}, completion: { finished in
self.circle.removeFromSuperlayer()
self.circleFrame.removeFromSuperview()
self.circleFrame.layer.removeAllAnimations()
self.createCircle()
self.score = self.score + 1
self.scoreLabel.text = "Taps: " + String(self.score)
self.tapsLabel.text = "Taps: " + String(self.initialTaps + self.score)
})
func createCircle() {
let randomX = generateRandomX()
let randomY = generateRandomY()
circleCenter = generateCircleCenter(x: randomX, y: randomY)
circleFrame.frame = CGRect(x: randomX, y: randomY, width: 100, height: 100)
circleFrame.alpha = 1.0
self.view.addSubview(circleFrame)
circle.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 100, height: 100), cornerRadius: 50).cgPath
circle.fillColor = UIColor(red: 0, green: greenValue/255, blue: 0.6, alpha: 1.0).cgColor
circle.strokeColor = UIColor(red: 1, green: greenValue/255, blue: 0, alpha: 1.0).cgColor
circle.lineWidth = 0
circleFrame.layer.addSublayer(circle)
}
I have tried removing all the animations among other things but it always appears smaller. Any help on why this happens would be great.
Here is how it looks the first time createCircle() is called.
This is how it looks when it is called from the animation.
I think is enough to set removedOnCompletion to true, so CAAnimation will reset to original size.
Give a try ! :)

How draw a custom label border 3 sides right and 1 rounded

I would like to draw the border of a label (UILabel) with three straight sides and a rounded as you can see an example picture: example label.
I use X-Code 7 and Swift 2.1
You can create a shape layer and use it in the label. I tried to get close to the sample in Playground:
import UIKit
import XCPlayground
let label = UILabel(frame: CGRect(x: 50, y: 170/2, width: 100, height: 30))
let rectanglePath = UIBezierPath(roundedRect: CGRectMake(1.5, 1.5, 97, 27), byRoundingCorners: [UIRectCorner.TopRight, UIRectCorner.BottomRight], cornerRadii: CGSizeMake(15, 15))
rectanglePath.closePath()
let color = [#Color(colorLiteralRed: 0.8442155122756958, green: 0.9805876612663269, blue: 0.9611368179321289, alpha: 1)#]
color.setFill()
rectanglePath.fill()
color.setStroke()
rectanglePath.lineWidth = 3
rectanglePath.stroke()
let mask = CAShapeLayer()
mask.path = rectanglePath.CGPath
label.textAlignment = .Center
label.backgroundColor = [#Color(colorLiteralRed: 0.990426778793335, green: 0.5112959146499634, blue: 0.4327127933502197, alpha: 1)#]
label.text = "Welcome...."
label.font = UIFont.systemFontOfSize(10)
label.layer.mask = mask
let view = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
view.backgroundColor = color
view.addSubview(label)
XCPShowView("Label", view: view)

Swift Playground XCPShowView "Unable to satisfy constraints"

I'm trying to get a Live View to show a simple animation in a Swift Playground. Whenever I import the XCPlayground framework to execute the XCPShowView function i get this error:
Playground execution failed: error: Couldn't lookup symbols:_CGPointMake
The error changes for a few other "symbols" as well, including CGRectMake.
After being advised to modifying my code to remove the "make" from methods such as CGRectMake I still get an error from Xcode when I try to animate my view. The error message is really long, but basically it says
"Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want."
Here is the code I am trying to work with:
//Circle Button
class timerButtonGraphics: UIView {
override func drawRect(rect: CGRect) {
let colorGreen = UIColor(red: 0.310, green: 0.725, blue: 0.624, alpha: 1.000)
let colorRed = UIColor(red: 241/255, green: 93/255, blue: 79/255, alpha: 100)
var bounds = self.bounds
var center = CGPoint()
center.x = bounds.origin.x + bounds.size.width / 2
center.y = bounds.origin.y + bounds.size.height / 2
var radius = 61
var path:UIBezierPath = UIBezierPath()
path.addArcWithCenter(center, radius: CGFloat(radius), startAngle: CGFloat(0.0), endAngle: CGFloat(Float(M_PI) * 2.0), clockwise: true)
path.strokeWithBlendMode(kCGBlendModeNormal, alpha: 100)
path.lineWidth = 2
if strokeRed == true {
colorRed.setStroke()
}
else {
colorGreen.setStroke()
}
path.stroke()
}
var strokeRed = true
}
var test = timerButtonGraphics(frame: CGRect(x: 0, y: 400, width: 400, height: 400))
UIView.animateWithDuration(2.0, delay: 2, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: nil, animations: {
test.transform = CGAffineTransformMakeTranslation(0.5, 0)
}, completion: nil)
XCPShowView("Circle Animation", test)
try with this, maybe it can help you
test.setTranslatesAutoresizingMaskIntoConstraints(false)

Resources