Sample Chart
When I provide data for Bar Chart it appears with little offset. I thought about stacked Bar Chart, but it was wrong - that how I provide sample data for chart:
var barEntries = [BarChartDataEntry]()
barEntries.append(BarChartDataEntry(x: 0, y: 0))
barEntries.append(BarChartDataEntry(x: 4, y: 1))
barEntries.append(BarChartDataEntry(x: 8, y: 24))
barEntries.append(BarChartDataEntry(x: 12, y: 37))
barEntries.append(BarChartDataEntry(x: 16, y: 27))
barEntries.append(BarChartDataEntry(x: 20, y: 11))
let barDataSet = BarChartDataSet(values: barEntries, label: nil)
let barData = BarChartData(dataSet: barDataSet)
barData.barWidth = 4
barChartView.data = barData
All barEntries was created with BarChartDataEntry initializers for non-stacked bar. Now I have no idea why bar doesn't start at 0.
try set barChartView.leftAxis.axisMinimum = 0 or 'barChartView.rightAxis.axisMinimum = 0' or barChartView.xAxis.axisMinimum = 0. Check ChartsDemo.
initialise barEntries with [BarChartDataEntry(x: 0, y: 0)] rather than appending BarChartDataEntry(x: 0, y: 0).
Related
I wanted to create a video timeline for my exported videos like in this image so my plan was creating a preview view and export the image from view and added to AVMutableVideoComposition as layer and animate it with AVVideoCompositionCoreAnimationTool but most the resources that I found is either obj-c or didn't fit to my use case. Code is for adding text but I thought I can change it later to image if this works. But I feel like I'm not able to show layers at all.
My app also heavily uses VideoFlint's [Cabbage][2] library for exporting videos and adding watermark so if adding is possible with Cabbage I'm also up for it.
var animationLayer = CALayer()
animationLayer.bounds = .init(x: 0, y: 0, width: 1080, height: 1920)
var titleLayer = CATextLayer()
titleLayer.string = "Test"
titleLayer.font = UIFont.systemFont(ofSize: 30)
titleLayer.bounds = .init(x: 20, y: 200, width: 200, height: 100)
animationLayer.addSublayer(titleLayer)
titleLayer.anchorPoint = .init(x: 0.5, y: 0.5)
let animation = CAKeyframeAnimation(keyPath: #keyPath(CALayer.contentsRect))
animation.duration = 5
animation.calculationMode = CAAnimationCalculationMode.discrete
animation.repeatCount = .infinity
animation.values = [
CGRect(x: 0, y: 0, width: 1, height: 1/3.0),
CGRect(x: 0, y: 1/3.0, width: 1, height: 1/3.0),
CGRect(x: 0, y: 2/3.0, width: 1, height: 1/3.0)
] as [CGRect]
animation.beginTime = AVCoreAnimationBeginTimeAtZero
animation.fillMode = CAMediaTimingFillMode.backwards
animation.isRemovedOnCompletion = false
titleLayer.add(animation, forKey: "test")
var parentLayer = CALayer()
var videoLayer = CALayer()
parentLayer.bounds = .init(x: 0, y: 0, width: 1080, height: 1920)
parentLayer.anchorPoint = .init(x: 0, y: 0)
parentLayer.position = .init(x: 0, y: 0)
videoLayer.bounds = .init(x: 0, y: 0, width: 1080, height: 1920)
parentLayer.addSublayer(videoLayer)
videoLayer.anchorPoint = .init(x: 0.5, y: 0.5)
videoLayer.position = .init(x: 0, y: 0)
videoLayer.backgroundColor = UIColor.red.cgColor
parentLayer.backgroundColor = UIColor.blue.cgColor
animationLayer.anchorPoint = .init(x: 0.5, y: 0.5)
animationLayer.position = .init(x: 0, y: 0)
videoLayer.addSublayer(animationLayer)
videoComposition?.animationTool = AVVideoCompositionCoreAnimationTool.init(postProcessingAsVideoLayer: videoLayer, in: parentLayer)
[2]: https://github.com/VideoFlint/Cabbage
My issue is that when I press the button that runs the dealToPlayer function(), everything acts as if a card has been dealt, updates total value of cards dealt, but it does not show any animation of the card being dealt or placed. Why might this be? I am not using auto layout for this scene at all.
func dealToPlayer() {
let index = Int(arc4random_uniform(UInt32(deckCards.count)))
let drawnCard = deckCards.remove(at: index)
randomCards.append(drawnCard)
randomCard = randomCards[3 + cardSelect]
image = UIImageView(frame: CGRect(x: self.deckLocation.x, y: self.deckLocation.y, width: self.width, height: self.height))
image.image = mapping[randomCard]
cardsOut = cardsOut + 1
print("cards out is currently: \(cardsOut)")
cardSelect = cardSelect + 1
UIView.animate(withDuration: 0.5, delay: 1.5, options: [], animations: {
self.image.frame = CGRect(x: self.cardTwoLocation.x - (self.cardsOut * self.thirdWidth), y: self.cardTwoLocation.y, width: self.width, height: self.height)
}, completion: nil)
checkPlayerValue()
}
First, make sure your image view is added to your view controller.
Second, make sure your animation is called by putting a break point.
Third, print out the location and make sure the new x and y are valid, and they are different than the previous x and y.
Here is a sample duplicate of your code an it works fine
image = UIImageView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
image.backgroundColor = .red
self.view.addSubview(image)
UIView.animate(withDuration: 0.5, delay: 1.5, options: [], animations: {
self.image.frame = CGRect(x: 200, y: 200, width: 100, height: 100)
}, completion: nil)
How can I fit a subView to the Proper Dimensions of the view I have Created in the story board?
For example
self.popUpView.addSubview(chart)
is presenting my display that i would like to span over the view I have in the story board.
class PopVC: UIViewController {
#IBOutlet weak var popUpView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let chart = Chart(frame: self.popUpView.frame)
let data = [(x: 0.0, y: 0), (x: 3, y: 2.5), (x: 4, y: 2), (x: 5, y: 2.3), (x: 7, y: 3), (x: 8, y: 2.2), (x: 9, y: 2.5)]
let series = ChartSeries(data: data)
series.area = true
chart.xLabels = [0, 3, 6, 9, 12, 15, 18, 21, 24]
chart.xLabelsFormatter = { String(Int(round($1))) + "h" }
chart.add(series)
//Circle Edge on barChartView
popUpView.layer.cornerRadius = 10
popUpView.layer.masksToBounds = true
self.popUpView.addSubview(chart)
}
#IBAction func closePopUp(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}//END CLASS
You haven't really posted what isn't working about your solution, but the immediate thing I notice is that you're setting the frame of your Chart to popUpView.frame, when you should set it to popUpView.bounds. This will ensure the origin of Chart is the origin of popUpView within popUpView's coordinate system.
So, to show the example, change your initialization code to this:
let chart = Chart(frame: self.popUpView.bounds)
If you want to create a rect that makes the chart the same size as popUpView, but 20pt from the bottom (for example) you could say:
let chart = Chart(frame: CGRect(x: 0, y: 0, width: self.popUpView.bounds.size.width, height: self.popUpView.bounds.size.height - 20))
Maybe you want it to be half the height of popUpView:
let chart = Chart(frame: CGRect(x: 0, y: 0, width: self.popUpView.bounds.size.width, height: self.popUpView.bounds.size.height / 2))
Etc.
I can generate a square with this standard code.
func drawSquare() {
let width:CGFloat = 100
var square = UIBezierPath()
square.moveToPoint(CGPoint(x: 0, y: 0))
square.addLineToPoint(CGPoint(x: width, y: 0))
square.addLineToPoint(CGPoint(x: width, y: width))
square.addLineToPoint(CGPoint(x: 0, y: width))
square.lineWidth = 5
square.closePath()
UIColor.blackColor().setStroke()
square.stroke()
}
However, if I want to draw each addLineToPoint() segment in two steps, my square no longer draws correctly.
func drawSquare2Steps() {
let width:CGFloat = 200
let mult:CGFloat = 2
var square = UIBezierPath()
square.moveToPoint(CGPoint(x: 0, y: 0))
square.addLineToPoint(CGPoint(x: 100, y: 0)) // 1
square.addLineToPoint(CGPoint(x: 200, y: 0)) // 2
square.addLineToPoint(CGPoint(x: 200, y: 100)) // 3
square.addLineToPoint(CGPoint(x: 200, y: 200)) // 4
square.addLineToPoint(CGPoint(x: 100, y: 200)) // 5
square.addLineToPoint(CGPoint(x: 0, y: 200)) //6
square.lineWidth = 5
square.closePath() // 7
UIColor.orangeColor().setStroke()
square.stroke()
}
Here's the path that I see:
I tried to describe this function in this image:
My final goal isn't to draw a square but a more complicated path. The square simply illustrates the problem with my complex path.
Nothing is wrong except that your view size is (100, 100) but the square size is (200,200), so you don't see the whole square.
I want to replicate the 3D rotating object shown at the 6th second of this video on iOS. I don't have any 3D animations/games experience, so I don't know where to start. I have looked a little and found this tutorial of Ray Wenderlich. I think I can change the shape from cube to a rectangular prism, and move it around while it's rotating, but I want it to have some logo, text, etc. on it in 3D. This is where I'm stuck.
Any suggestions or tutorials related to this kind of work?
You need to get familiar with general concepts of 3D programming first because your question is ambiguous. What do you mean by on it?
That cube is comprised of several different arrays of data defining different properties of each vertex on each triangular face. So if you want 3D text coming out of the cube you will need to redefine those arrays.
There are a tonne of resources for learning 3D programing and the concepts are generally universal.
This is what i have done for rotate cube. Hope it helps.
var cubeLayer = CATransformLayer()
var layer1 = CALayer()
var layer2 = CALayer()
var layer3 = CALayer()
var layer4 = CALayer()
var pt = CATransform3DIdentity
pt.m34 = -1.0 / 500.0
yourView.layer.sublayerTransform = pt
layer1.backgroundColor = UIColor.red.cgColor
layer1.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
layer1.transform = CATransform3DTranslate(layer1.transform, 0, 0, 100)
cubeLayer.addSublayer(layer1)
layer2.backgroundColor = UIColor.green.cgColor
layer2.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
layer2.transform = CATransform3DTranslate(layer2.transform, -100, 0, 0)
layer2.transform = CATransform3DRotate(layer2.transform, .pi / 2, 0, 1, 0)
cubeLayer.addSublayer(layer2)
layer3.backgroundColor = UIColor.yellow.cgColor
layer3.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
layer3.transform = CATransform3DTranslate(layer3.transform, 100, 0, 0)
layer3.transform = CATransform3DRotate(layer3.transform, .pi / 2, 0, 1, 0)
cubeLayer.addSublayer(layer3)
layer4.backgroundColor = UIColor.blue.cgColor
layer4.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
layer4.transform = CATransform3DTranslate(layer4.transform, 0, 0, -100)
cubeLayer.addSublayer(layer4)
cubeLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
yourView.layer.addSublayer(cubeLayer)
add gesture to your view and rotate it using swap gesture, using below code you can rotate cube from left to right.
let swiperight = UISwipeGestureRecognizer(target: self, action: #selector(self.swiperight))
swiperight.direction = .right
yourView.addGestureRecognizer(swiperight)
#objc func swiperight(_ gestureRecognizer: UISwipeGestureRecognizer) {
self.cubeLayer.transform = CATransform3DRotate(self.cubeLayer.transform, .pi / -1.5, 0, 1, 0)
self.cubeLayer.transform = CATransform3DRotate(self.cubeLayer.transform, .pi / 4
, 0, 1, 0)
self.cubeLayer.transform = CATransform3DRotate(self.cubeLayer.transform, .pi / 2
, 0, 1, 0)
}