Subtraction of CGFloats, ambiguity error Swift 3 - swift3

I am trying to subtract some CGFloats, that are defined in this way:
var panelHeight:CGFloat!
When I try to do (screenHeight - panelHeight - tabBarHeight) in the following code, I get an error saying that I cannot apply a binary operator on CGFloat and CGFloat!, which doesn't make much sense, because all three floats are declared with !. If I replace tabBarHeight with tabBarHeight!, then I get an error called "Ambiguous reference to member -".
collisionBehavior.addBoundaryWithIdentifier("upperBoundary" as NSCopying, fromPoint: CGPoint(x: 0, y: screenHeight - panelHeight - tabBarHeight), toPoint: CGPoint(x: boundaryX, y: screenHeight - panelHeight - tabBarHeight))

I can't find the bug report, but this is a known bug. A workaround is to cast the first or the second variable to a non-optional, like so:
(screenHeight as CGFloat) - panelHeight - tabBarHeight

Related

SwiftUI - Snapshot a variable as a value instead of a pointer so it is not updated during DragGesture .onchanged lifecycle

I am trying to move a CGPoint (greenPoint) by moving another one (bluePoint). The distance and angle must remained the same. In order to capture that, I store the x delta as adjacent and y delta as opposite. My issue is that when I move the blue point, the adjacent and opposite values get updated and therefore the greenPoint stays in the same place.
I was thinking I could maybe take a snapshot of the values before the .onChanged, but can’t work out how? Code is below.
Circle()
.strokeBorder(.white, lineWidth: 2)
.background(Circle().fill(.blue))
.frame(width:10, height:10)
.position(bluePoint)
.gesture(DragGesture()
.onChanged{state in
greenPoint = CGPoint(x: bluePoint.x+adjacent, y: bluePoint.y+opposite)
bluePoint = state.location
})
Note: I need to keep adjacent and opposite as variables rather than static values, because in another part of the code moving the greenPoint is permitted while the bluePoint stays still.
Thanks!
Thanks for the suggestions. Got it to work with the following:
let adj = baseCoords.adjacent
let op = baseCoords.opposite
…
Circle()
.strokeBorder(.white, lineWidth:2)
.background(Circle().fill(.blue))
.frame(width:12, height:12)
.position(bluePoint)
.gesture(DragGesture()
.onChanged{state in
bluePoint = state.location
greenPoint.x = bluePoint.x + adj
greenPoint.y = bluePoint.y + op
}
)
By copying into 2 new variables, the adj and op values do not update during the .onChanged.

Getting Error: "Type of expression is ambiguous without more context" when creating string literal - SwiftUI

While running my code I get the error 'Type of expression is ambiguous without more context' in a number of places and I don't know why. It seems like a string literal should not be ambiguous.
I'm running Xcode 11 GM and I do get it to work when I cast it to a String but then I get an error when setting the color for the Text. This is not solved by casting it to a color.
`let currentRed: Double = Double.random(in: 0..<1)
var body: some View {
return Text(String("Red \(Int(currentRed * 255.0))")) // <- Returns Error without cast to String
.foregroundColor(Color(red: self.currentRed, green: 0.0, blue: 0.0)) // <- Returns same error }
I expect to be able to set the foregroundColor but I keep on getting this error. Is this a bug?
I have no errors when I use this syntax:
Text("Red \(currentRed * 255.0)")
.foregroundColor(Color(red: self.currentRed, green: 0.0, blue: 0.0))
And here's the output:
You're using at least three type conversions - String, Int, and whatever you call \() where it appears you just want the last one.
If you wish to display the integer value, just change your line to:
Text("Red " + String(Int(currentRed * 255.0)))
.foregroundColor(Color(red: self.currentRed, green: 0.0, blue: 0.0))
Sample output:
(Keep in mind, since you are adding a random number, the output isn't identical!)

how to use Element.status(); in Raphael.js

the documentation is too breif.
can anyone knowa about how to use Element.status() in Raphael.js?
very appreciate if you can give a demo.
Element.status shows the current animation applied to an element OR you can set the status on a particular animation.
Think of an animation interpolating between 0 and 1. So half way through an animation, it would have a value of 0.5. This is applied to whatever attribute is being animated. (So if animating x from 0 to 100 half way through, status will be 0.5 and x will be 50, not accounting for any easing applied like bounce).
So lets suppose instead of creating a nice smooth interpolation between attributes, we want to make an element move in 10 discrete steps. We can set the status each time of an animation manually. Example.
var raphAnimation = Raphael.animation( { x: 100, y: 100 }, 1000);
rect.status( raphAnimation, 0.5 )
example jsfiddle
var rect = paper.rect(10, 20, 300, 200);
var raphAnimation = Raphael.animation( { x: 100, y: 100 }, 1000);
for( var c = 1; c <= 10; c++ ) {
(function() {
var step = c
setTimeout( function() {
rect.status( raphAnimation, 0.1 * step )
}, step * 200)
})();
}
Note: If you repeat using the status set command, I think it will take the animation as fresh. So suppose the animation is from 0->100 and you set status to be 0.5 it will go half way. Now suppose you do the same and call it again with 0.5, it will now be 0.5 of the 'remainder' as it now only has half the distance to traverse.

How to stop NSExpression from rounding

I've been making a calculator in Swift 3, but have run into some problems.
I have been using NSExpression to calculate the users equation, but the answer is always rounded.
To check that the answer was rounded, I calculated 3 / 2.
let expression = NSExpression(format: "3 / 2");
let answer: Double = expression.expressionValue(with: nil, context: nil) as! Double;
Swift.print(String(answer));
The above code outputs 1.0, instead of 1.5.
Does anyone know how to stop NSExpression from rounding? Thanks.
The expression is using integer division since your operands are integers. Try this instead:
let expression = NSExpression(format: "3.0 / 2.0");
let answer: Double = expression.expressionValue(with: nil, context: nil) as! Double;
Swift.print(String(answer));
Consider the following code:
let answer = Double(3 / 2)
answer in this case would still be 1.0 since 3 / 2 is evaluated to 1 before being inserted in the Double initializer.
However, this code would give answer the value of 1.5:
let answer = Double(3.0 / 2.0)
This is because 3.0 / 2.0 will be evaluated based on the division operation for Double instead of the division operation of Integer.

Swift Double is Not Convertible to CGFloat

I'm trying to draw a simple circle when I get to the following line I get the error "Double is Not Convertable to CGFloat under the startAngle = 0.0
path.addArcWithCenter(center, radius: radius, startAngle: 0.0, endAngle: Float(M_PI) * 2.0, clockwise: true)
How do I "cast" 0.0 to make it CGFloat in Swift?
The complete function I am writing:
func drawCircle() {
// Drawing code
var bounds:CGRect = secondView.bounds
var center = CGPoint()
center.x = bounds.origin.x + bounds.size.width / 2.0
center.y = bounds.origin.y + bounds.size.height / 2.0
var radius = (min(bounds.size.width, bounds.size.height) / 2.0)
var path:UIBezierPath = UIBezierPath()
path.addArcWithCenter(center, radius: radius, startAngle: CGFloat(0.0), endAngle: Float(M_PI) * 2.0, clockwise: true)
path.stroke()
}
Convert the values that need to be CGFloat to a CGFloat.
path.addArcWithCenter(center, radius: CGFloat(radius), startAngle: CGFloat(0.0), endAngle: CGFloat(M_PI) * 2.0, clockwise: true)
startAngle probably shouldn't need to be converted though if you're just passing a literal. Also note that this isn't a C style cast, but actually converting between different Swift Types.
Edit: Looking at your whole function, this works.
func drawCircle() {
// Drawing code
var bounds:CGRect = self.view.bounds
var center = CGPoint()
center.x = bounds.origin.x + bounds.size.width / 2.0
center.y = bounds.origin.y + bounds.size.height / 2.0
var radius = (min(bounds.size.width, bounds.size.height) / 2.0)
var path:UIBezierPath = UIBezierPath()
path.addArcWithCenter(center, radius: CGFloat(radius), startAngle: CGFloat(0.0), endAngle: CGFloat(Float(M_PI) * 2.0), clockwise: true)
path.stroke()
}
You must type cast it via CGFloat(0.0). CGFloat has been adjusted to evaluate differently throughout the beta version of Xcode 6 due to the fact that in Obj-C, CGFloat casts to either a float or a double depending on the target (64 bit versus 32 bit). You must type cast a number to CGFloat in Swift to use a CGFloat as you're never guaranteed to have a float or a double (because this is dependent on the environment). This way, Swift won't throw a fit and will still be 'type' safe.
This error will disappear in Swift 5.5.
Maybe it's not a good idea, but I used NSNumber to convert Double to Float, then to CGFloat.
let myFloat = NSNumber.init(value: myDouble).floatValue
let myCGFloat = CGFloat(myFloat)