Swift Some Lottie Animations Distorted - ios

I am using Lottie in my iOS app, and have changed the colors of all animations to fit my color palatte. All animations are json file that i download directly from the lottie editor. The lottie editor shows an animation working, but the result is distorted for some and fine for others, using the same method. Is there something wrong with the JSON that i can fix?
func expandModal() {
if state != .contracted {
return
}
dismissMe = false
contractedFrame = self.frame
solutionLabel.alpha = 0
state = .gettingBigger
let animation = Animation.named(name)
animationView.animation = animation
animationView.loopMode = .loop
animationView.frame = leftArrow.frame
leftArrow.alpha = 0
addSubview(animationView)
UIView.animate(withDuration: 0.5) { [self] in
frame = CGRect(x: 0, y: 0, width: 300, height: 400)
center = self.superview!.center
layer.cornerRadius = 10
leftArrow.frame = CGRect(x: 10, y: 20, width: modalType == .Points ? 100 : 150, height: modalType == .Points ? 100 : 150)
leftArrow.center.x = frame.width / 2
animationView.frame = leftArrow.frame
titleLabel.alpha = 1
titleLabel.numberOfLines = 2
titleLabel.frame = CGRect(x: 24*kWidthFactor, y: leftArrow.frame.maxY + 24 * kHeightFactor, width: self.frame.width - 48 * kWidthFactor, height: 1000)
titleLabel.font = sfUITextBold(fontSize: 24 * kHeightFactor)
titleLabel.textAlignment = .center
titleLabel.sizeToFit()
titleLabel.center.x = self.frame.width / 2
addSubview(titleLabel)
descriptionLabel.alpha = 1
descriptionLabel.numberOfLines = 0
descriptionLabel.frame = CGRect(x: 24*kWidthFactor, y: titleLabel.frame.maxY + 12 * kHeightFactor, width: self.frame.width - 48 * kWidthFactor, height: 1000)
descriptionLabel.text = descriptionString
descriptionLabel.font = sfUITextRegular(fontSize: 18 * kHeightFactor)
descriptionLabel.sizeToFit()
addSubview(descriptionLabel)
} completion: { [self] _ in
self.state = .expanded
animationView.play()
}
}
Pathfinder json image editor
Architect json image
Video of app

Related

Offset 2D-Matrix: equal spacing in pattern

Let's first take a look at the Screenshot:
My problem:
I just cannot figure out how to change the spacing between the horizontal lines. This spacing is a little bit too wide, as you can see compared to the vertical lines.
This is how I implemented the pattern of UIButtons:
func buildBoard(){
for i in 0...8{
for j in 0...8{
rowBtnArr.append(setupBtn(x: i, y: j))
}
}
}
func setupBtn( x: Int, y: Int)->UIButton{
let btnSize = Int(UIScreen.main.bounds.width / 10) //40
let buffer = 1
if(y%2==0){ //even lines: normal
button = UIButton(frame: CGRect(x: x*btnSize, y: y*btnSize, width: btnSize-buffer, height: btnSize-buffer))
}else{ //odd lines: shift by 1/2 button width
button = UIButton(frame: CGRect(x: x*btnSize+(btnSize/2), y: y*btnSize, width: btnSize-buffer, height: btnSize-buffer))
}
button.layer.cornerRadius = 0.5 * button.bounds.size.width
//unimportant color and target lines are left out
return button
}
Thanks for any help!
SwiftHobby
I think one thing you have to consider is that because you are offsetting the rows every even row, there is more space vertically because the peak height of your circles matches up with the intersection of circles above it. So what I would do is subtract some number to the btnSize before you multiply it by y. This should tighten the y-spacing.
func setupBtn( x: Int, y: Int)->UIButton{
let btnSize = Int(UIScreen.main.bounds.width / 10) //40
let buffer = 1
if(y%2==0){ //even lines: normal
button = UIButton(frame: CGRect(x: x*btnSize, y: y*(btnSize-1), width: btnSize-buffer, height: btnSize-buffer))
}else{ //odd lines: shift by 1/2 button width
button = UIButton(frame: CGRect(x: x*btnSize+(btnSize/2), y: y*(btnSize-1), width: btnSize-buffer, height: btnSize-buffer))
}
button.layer.cornerRadius = 0.5 * button.bounds.size.width
//unimportant color and target lines are left out
return button
}
This way the y-spacing is closer than the x-spacing, accounting for the mismatch I was talking about earlier. You need to experiment with the y-spacing to get the visual difference you want, so my correction above might be weird looking as well.
maybe you want this effect:
I use your code and make some changes, and use a Array to cache all buttons's frame like blow:
// user a Array to cache all frames
lazy var framesMatrix: [[CGRect]] = Array(repeating: Array(repeating: CGRect.zero, count: 9), count: 9)
func setupBtn( x: Int, y: Int)->UIButton{
let btnCount = 10
let buffer: CGFloat = 1
let btnSize = (UIScreen.main.bounds.width - CGFloat(btnCount - 1) * buffer) / CGFloat(btnCount)
var button: UIButton = UIButton()
if y % 2 == 0 {
if y == 0 {
let frame = CGRect(x: CGFloat(x)*(btnSize+buffer), y: CGFloat(y)*btnSize, width: btnSize, height: btnSize)
framesMatrix[x][y] = frame
button = UIButton(frame: frame)
} else {
let lastFrame = framesMatrix[x][y-1]
// Here is the change
let newCenterY = lastFrame.midY + sqrt(3.0) * 0.5 * (btnSize+buffer);
let frame = CGRect(x: lastFrame.minX - btnSize * 0.5 , y: newCenterY - btnSize * 0.5, width: btnSize, height: btnSize);
framesMatrix[x][y] = frame
button = UIButton(frame: frame)
}
} else {
let lastFrame = framesMatrix[x][y-1]
// Here is the change
let newCenterY = lastFrame.midY + sqrt(3.0) * 0.5 * (btnSize+buffer);
let frame = CGRect(x: lastFrame.midX + buffer * 0.5, y: newCenterY - btnSize * 0.5 , width: btnSize, height: btnSize);
framesMatrix[x][y] = frame
button = UIButton(frame: frame)
}
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.backgroundColor = UIColor.black
//unimportant color and target lines are left out
return button
}

Animation with UIBezierPath - Object gets fixed on the top left corner

I am trying to create an animation in swift to make a few ballons float from the bottom of the screen to the top. However in the middle of the animation one of the balloons gets fixed on the top left corner of the screen and does not disappear even when the animation finishes.
Please watch this video to see what I am talking about:
https://imgur.com/a/tyS0Q5u
Here is my code. I don't really know what I am doing wrong.
func presentVictoryView() {
blackView.isHidden = false
for _ in 0 ... 20 {
let objectView = UIView()
objectView.translatesAutoresizingMaskIntoConstraints = false
objectView.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
//objectView.backgroundColor = .clear
//objectView.alpha = CGFloat(0.9)
objectView.isHidden = false
let ballon = UILabel()
ballon.translatesAutoresizingMaskIntoConstraints = false
ballon.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
//ballon.backgroundColor = .clear
//ballon.alpha = CGFloat(0.9)
ballon.text = "🎈"
ballon.font = UIFont.systemFont(ofSize: 60)
objectView.addSubview(ballon)
NSLayoutConstraint.activate([
ballon.centerXAnchor.constraint(equalTo: objectView.centerXAnchor),
ballon.centerYAnchor.constraint(equalTo: objectView.centerYAnchor)
])
blackView.addSubview(objectView)
let randomXOffset = Int.random(in: -120 ..< 200)
let path = UIBezierPath()
path.move(to: CGPoint(x: 270 + randomXOffset, y: 1000))
path.addCurve(to: CGPoint(x: 100 + randomXOffset, y: -300), controlPoint1: CGPoint(x: 300 - randomXOffset, y: 600), controlPoint2: CGPoint(x: 70 + randomXOffset, y: 300))
let animation = CAKeyframeAnimation(keyPath: "position")
animation.path = path.cgPath
animation.repeatCount = 1
animation.duration = Double.random(in: 4.0 ..< 7.0)
//animation.timeOffset = Double(arc4random_uniform(50))
objectView.layer.add(animation, forKey: "animate position along path")
}
//objectView.isHidden = true
//self?.newGame()
}
Thank you for your help! :)
You should use delegate to detect end of animation and remove bubbleView then.
func presentVictoryView() {
blackView.isHidden = false
for _ in 0 ... 20 {
let objectView = UIView()
objectView.translatesAutoresizingMaskIntoConstraints = false
objectView.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
//objectView.backgroundColor = .clear
//objectView.alpha = CGFloat(0.9)
objectView.isHidden = false
let ballon = UILabel()
ballon.translatesAutoresizingMaskIntoConstraints = false
ballon.frame = CGRect(x: 50, y: 50, width: 20, height: 100)
//ballon.backgroundColor = .clear
//ballon.alpha = CGFloat(0.9)
ballon.text = "🎈"
ballon.font = UIFont.systemFont(ofSize: 60)
objectView.addSubview(ballon)
NSLayoutConstraint.activate([
ballon.centerXAnchor.constraint(equalTo: objectView.centerXAnchor),
ballon.centerYAnchor.constraint(equalTo: objectView.centerYAnchor)
])
blackView.addSubview(objectView)
let randomXOffset = Int.random(in: -120 ..< 200)
let path = UIBezierPath()
path.move(to: CGPoint(x: 270 + randomXOffset, y: 1000))
path.addCurve(to: CGPoint(x: 100 + randomXOffset, y: -300), controlPoint1: CGPoint(x: 300 - randomXOffset, y: 600), controlPoint2: CGPoint(x: 70 + randomXOffset, y: 300))
let animation = CAKeyframeAnimation(keyPath: "position")
animation.path = path.cgPath
animation.repeatCount = 1
// add these
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
let delegate = BubbleAnimDelegate()
delegate.didFinishAnimation = {
objectView.removeFromSuperview()
}
animation.delegate = delegate
// upto here
animation.duration = Double.random(in: 4.0 ..< 7.0)
//animation.timeOffset = Double(arc4random_uniform(50))
objectView.layer.add(animation, forKey: "animate position along path")
}
//objectView.isHidden = true
//self?.newGame()
}
class BubbleAnimDelegate: NSObject, CAAnimationDelegate {
var didFinishAnimation: (()->Void)?
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
didFinishAnimation?()
}
}

ScrollView snap to center

I want to setup my scrollView like this video (I know in video use collectionview bu for some reason I want convert this effect to scrollView)
https://www.dropbox.com/s/kj6xgj68gz6258p/ScreenRecording_06-26-2018%2019-15-43.MP4
3 important thing:
scroll must snap to center when scrolling
resize current item (forward item is bigger than backward item)
swift
UPDATE:
var ScrollView = UIScrollView()
var arr : Array<UIColor> = [.red,.blue,.green]
override func viewDidLoad() {
super.viewDidLoad()
ScrollView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(ScrollView)
ScrollView.widthAnchor.constraint(equalToConstant: self.view.frame.size.width).isActive = true
ScrollView.heightAnchor.constraint(equalToConstant: 320).isActive = true
ScrollView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 0).isActive = true
ScrollView.alwaysBounceVertical = false
ScrollView.isPagingEnabled = true
ScrollView.contentSize = CGSize(width: 3.0 * self.view.frame.size.width, height: 320)
ScrollView.contentOffset = CGPoint(x: view.frame.size.width, y: 0)
ScrollView.center = self.view.center
for i in 0..<3 {
let viewBG = UIView()
viewBG.backgroundColor = arr[i]
if (i == 0) {
viewBG.frame = CGRect(x: view.frame.size.width * CGFloat(i) + 125, y: 0, width: view.frame.size.width - 100, height: 320)
} else if(i == 1) {
viewBG.frame = CGRect(x: view.frame.size.width * CGFloat(i) + 50, y: 0, width: view.frame.size.width - 100, height: 320)
} else {
viewBG.frame = CGRect(x: view.frame.size.width * CGFloat(i) - 25, y: 0, width: view.frame.size.width - 100, height: 320)
}
ScrollView.addSubview(viewBG)
}
}
thanks guys
Use iCarousal. It is easy to implement and Swift example is also available.
Following is link -
https://github.com/nicklockwood/iCarousel

Adding UIButtons in an arc

I'm trying to make a button that when tapped forms an arc of options. I'm able to draw the options on a diagonal line (see image below) but can't figure out how to display them in an arc. Any suggestions?
What I'm getting
Code
let resourceObjects = ["sprite", "shape", "text", "function", "sound", "variable", "list"]
let radius : CGFloat = 120
var shiftX : CGFloat = 0
var shiftY : CGFloat = radius
// x^2 + y^2 = radius
for o in resourceObjects {
let cell = UIButton()
cell.frame = CGRect(x: sender.frame.origin.x + shiftX, y: sender.frame.origin.y + 50 - shiftY, width: screenWidth, height: 30)
self.view.addSubview(cell)
let img = UIImageView()
img.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
img.image = UIImage(named: String(o) + ".png")
cell.addSubview(img)
let lbl = UILabel()
lbl.frame = CGRect(x: 27, y: 0, width: screenWidth - 60, height: 30)
lbl.font = UIFont.systemFont(ofSize: 12)
lbl.text = o
lbl.sizeToFit()
lbl.frame = CGRect(x: 27, y: 0, width: lbl.frame.width, height: lbl.frame.height)
cell.addSubview(lbl)
cell.frame = CGRect(x: sender.frame.origin.x + shiftX, y: sender.frame.origin.y + 50 - shiftY, width: lbl.frame.width + 27, height: 30)
shiftX += radius / CGFloat(resourceObjects.count)
shiftY -= radius / CGFloat(resourceObjects.count)
options.append(cell)
}
Use trig to calculate the positions: vary your angle from 0 to 2 pi for a full circle. Use a fraction of that range for a part of a circle.
x = cos(angle) * radius + origin.x
y = sin(angle) * radius + origin.y

Swift Error - 'Cannot invoke value of type 'SwiftStockChart.LabelForValueGetter' (aka'(Int) -> String') with argument list '(Value:Int)'

I am getting an error when I am trying to set the chart points from the Yahoo Finance API using Swift.
The error says
Cannot invoke value of type 'SwiftStockChart.LabelForValueGetter'
(aka'(Int) -> String') with argument list '(Value:Int)'
And this is on line.
let text = labelForIndex(index: i)
The full code is:
func setChartPoints(points: [ChartPoint]) {
if points.isEmpty { return }
dataPoints = points
computeBounds()
if maxValue!.isNaN { maxValue = 1.0 }
for i in 0 ..< verticalGridStep! {
let yVal = axisHeight! + margin! - CGFloat((i + 1)) * axisHeight! / CGFloat(verticalGridStep!)
let p = CGPoint(x: (valueLabelPosition! == .right ? axisWidth! : 0), y: yVal)
let text = labelForValue(value: minValue! + (maxValue! - minValue!) / CGFloat(verticalGridStep!) * CGFloat((i + 1)))
let rect = CGRect(x: margin!, y: p.y + 2, width: self.frame.size.width - margin! * 2 - 4.0, height: 14.0)
let width = text.boundingRect(with: rect.size,
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes:[NSFontAttributeName : valueLabelFont!],
context: nil).size.width
let xPadding = 6
let xOffset = width + CGFloat(xPadding)
let label = UILabel(frame: CGRect(x: p.x - xOffset + 5.0, y: p.y, width: width + 2, height: 14))
label.text = text
label.font = valueLabelFont
label.textColor = valueLabelTextColor
label.textAlignment = .center
label.backgroundColor = valueLabelBackgroundColor!
self.addSubview(label)
axisLabels.append(label)
}
for i in 0 ..< horizontalGridStep! + 1 {
let text = labelForIndex(index: i)
let p = CGPoint(x: margin! + CGFloat(i) * (axisWidth! / CGFloat(horizontalGridStep!)) * 1.0, y: axisHeight! + margin!)
let rect = CGRect(x: margin!, y: p.y + 2, width: self.frame.size.width - margin! * 2 - 4.0, height: 14)
let width = text.boundingRect(with: rect.size,
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes:[NSFontAttributeName : indexLabelFont!],
context: nil).size.width
let label = UILabel(frame: CGRect(x: p.x - 5.0, y: p.y + 5.0, width: width + 2, height: 14))
label.text = text
label.font = indexLabelFont!
label.textAlignment = .left
label.textColor = indexLabelTextColor!
label.backgroundColor = indexLabelBackgroundColor!
self.addSubview(label)
axisLabels.append(label)
}

Resources