|= operator cannot be applied to two NSWindowMask operations - swift

In swift 4 this fails
self.window.styleMask |= NSWindowStyleMask.fullSizeContentView
and I'd also like to undo
self.window.styleMask ^= NSWindowStyleMask.fullSizeContentView
as I would in objective-c

In Swift, NSWindowStyleMask (in Swift 4, NSWindow.StyleMask) is OptionSet. You need to use methods defined for SetAlgebra.
Swift 4:
self.window!.styleMask.formUnion(NSWindow.StyleMask.fullSizeContentView)
self.window!.styleMask.formSymmetricDifference(NSWindow.StyleMask.fullSizeContentView)
The code below compiles both in Swift 3 & Swift 4:
self.window!.styleMask.formUnion(.fullSizeContentView)
self.window!.styleMask.formSymmetricDifference(.fullSizeContentView)

This is ugly
self.window.styleMask = NSWindowStyleMask(rawValue: NSWindowStyleMask.fullSizeContentView.rawValue + panel.styleMask.rawValue)
seems to work? The net affect is the content shrinks (by title height) when it's toggled. So I might to back to what I had been using - .borderless

Related

Array cannot be inferred Error in Xcode 12 with Swift 5

Here is the simple code:
var buffer = [UInt8](_data)
var sec_ivs = [UInt8](repeating: 0, count: 8);
memcpy(&sec_ivs + 3, &buffer, 5);
The Xcode stop building the project with the following error:
How can I rewrite this code to make it works again in Xcode 12? This code is working fine in Xcode 11, but Xcode 11 did not support iOS 14 debuging.Thanks for help.
You can pass the address of the (mutable) element storage of an array to a C function with
memcpy(&sec_ivs, buffer, 5)
but that does not work with offsets. Here you need to use withUnsafeMutableBytes() to obtain a buffer pointer, so that you can add an offset:
sec_ivs.withUnsafeMutableBytes {
memcpy($0.baseAddress! + 3, buffer, 5);
}
Note that the & operator is not needed for the second argument of memcpy() because that is a constant pointer argument.
A simpler solution would an assignment to a slice of the target array:
sec_ivs[3..<8] = buffer[0..<5]

Swift: How to disable integer overflow / underflow traps for a function

I'm importing some old C code into a swift project, and porting it across to pure swift code.
Some of it does "encryption" wherein it does something like
let a = UInt8(x) // e.g. 30
let b = a - 237
In C this just underflows and wraps around, which is fine for this particular function.
In swift this triggers a fatalError and terminates my program with EXC_BAD_INSTRUCTION because swift by default is designed to catch integer over/underflow.
I'm aware I can turn this checking off at the entire project level by compiling with -Ofast, but I'd really like to just turn off the overflow checking for this one line of code (or perhaps just the specific function itself).
Note: I specifically want to preserve the behaviour of the C function, not just promote things up to Int32 or Int64
This particular term seems really hard to google for.
Update: The answer is the Overflow operators, which are
&- for subtraction
&+ for addition
&* for multiply
I couldn't find them in my previous searching. Oops
You can use addWithOverflow or subtractWithOverflow class method of Int, UInt8 etc types
E.g. let b = UInt8.subtractWithOverflow(a, 237)
Apart from overflow operators (such as &+ , &* etc) you can make use of reporting overflow methods (available for integers) to know whether the arithmetic operation resulted in an overflow or not such as this example :
let int1 : Int8 = Int8.max //127
let int2: Int8 = 50
//this method provides a boolean flag
let (sum1,didOverflow ):(Int8,Bool) = int1.addingReportingOverflow(int2)
print("sum is \(sum1) and isOverflowing = \(didOverflow)")
//sum is -79 and isOverflowing is true
let sum = int1 &+ int2 //wont crash for overflows
let unsafeSum = int1.unsafeAdding(int2) //crashes whenever overflow

what does << mean in sprite kit collision categories?

My friend said that he implemented some code so that my collision detection would work better. What he put in I don't understand so I wanted to know what it means. More specifically what << means.
typedef NS_OPTIONS(NSUInteger, CollisionCategory){
rectangulo = (1 << 0),
circulo = (1 << 1)
thanks,
<3
This is totally unrelated to Xcode or sprite collision; the << is the C language left shift operator. If, as in your case, applied to integers, it performs a bitwise shift of the first argument by the second argument. In your case, the two expressions yield 1 and 2, respectively.

binary operator / cannot be applied to operands of type Int and Double [duplicate]

This question already has answers here:
Multiplying variables and doubles in swift
(2 answers)
So if string is not NilLiteralConvertible... what do some string functions return?
(1 answer)
Closed 7 years ago.
Hello brand new to Swift, and programming in general. Going through an exercise the code given is exactly:
//: Playground - noun: a place where people can play
import UIKit
let height = 12
let width = 10
let area = height * width
let areaInMeters = area / 10.762
But I get the error, "binary operator / cannot be applied to operands of type Int and Double".
After some digging around I found you can't operate on both an Integer and a Double. So I changed the last line to:
let areaInMeters = (Double)area / 10.762
Then I get the error, "Consecutive statements on a line must be separated by a ;" and it wants me to put the ; after area. None of this is making any sense to me.
Using El Capitan beta and Xcode 7 beta.
height and width will both be inferred as of type Int. Therefore area is also of type Int whilst 10.762 is a Double.
And in Swift safety is paramount so you'll need to have both operands of same type.
Solution is (as Eric D. suggested) is to convert area to a Double:
let areaInMeters = Double(area) / 10.762
Try instead adding a decimal point and a zero to the end of your height and width.
Like so:
let height = 12.0
let width = 10.0
And you won't have to worry about having to deal with an Integer.
Hope this helps. Happy Coding!

Weird casting needed in Swift

I was watching some of the videos at WWDC2014 and trying to code I liked, but one of the weird things I noticed is that Swift keeps getting mad at me and wanting me to cast to different number types. This is easy enough but in the videos at WWDC they did NOT need to do this. Here is an example from "What's New With Interface Builder":
-M_PI/2 keeps giving me the error: "Could not find an overload for '/' that accepts the supplied arguments'
Does anyone have a solution to this problem, that does NOT simply involve casting because there is clearly another way of doing this? I have many many more examples for similar problems to this.
if !ringLayer {
ringLayer = CAShapeLayer()
let innerRect = CGRectInset(bounds, lineWidth / 2.0, lineWidth / 2.0)
let innerPath = UIBezierPath(ovalInRect: innerRect)
ringLayer.path = innerPath.CGPath
ringLayer.fillColor = nil
ringLayer.lineWidth = lineWidth
ringLayer.strokeColor = UIColor.blueColor().CGColor
ringLayer.anchorPoint = CGPointMake(0.5, 0.5)
ringLayer.transform = CATransform3DRotate
(ringLayer.transform, -M_PI/2, 0, 0, 1)
layer.addSublayer(ringLayer)
}
ringLayer.frame = layer.bounds
Edit: NB: CGFloat has changed in beta 4, specifically to make handling this 32/64-bit difference easier. Read the release notes and don't take the below as gospel now: it was written for beta 2.
After a clue from this answer I've worked it out: it depends on the selected project architecture. If I leave the Project architecture at the default of (armv7, arm64), then I get the same error as you with this code:
// Error with arm7 target:
ringLayer.transform = CATransform3DRotate(ringLayer.transform, -M_PI/2, 0, 0, 1)
...and need to cast to a Float (well, CGFloat underneath, I'm sure) to make it work:
// Works with explicit cast on arm7 target
ringLayer.transform = CATransform3DRotate(ringLayer.transform, Float(-M_PI/2), 0, 0, 1)
However, if I change the target architecture to arm64 only, then the code works as written in the Apple example from the video:
// Works fine with arm64 target:
ringLayer.transform = CATransform3DRotate(ringLayer.transform, -M_PI/2, 0, 0, 1)
So to answer your question, I believe this is because CGFloat is defined as double on 64-bit architecture, so it's okay to use M_PI (which is also a double)-derived values as a CGFloat parameter. However, when arm7 is the target, CGFloat is a float, not a double, so you'd be losing precision when passing M_PI (still a double)-derived expressions directly as a CGFloat parameter.
Note that Xcode by default will only build for the "active" architecture for Debug builds—I found it was possible to toggle this error by switching between iPhone 4S and iPhone 5S schemes in the standard drop-down in the menu bar of Xcode, as they have different architectures. I'd guess that in the demo video, there's a 64-bit architecture target selected, but in your project you've got a 32-bit architecture selected?
Given that a CGFloat is double-precision on 64-bit architectures, the simplest way of dealing with this specific problem would be to always cast to CGFloat.
But as a demonstration of dealing with this type of issue when you need to do different things on different architectures, Swift does support conditional compilation:
#if arch(x86_64) || arch(arm64)
ringLayer.transform = CATransform3DRotate (ringLayer.transform, -M_PI / 2, 0, 0, 1)
#else
ringLayer.transform = CATransform3DRotate (ringLayer.transform, CGFloat(-M_PI / 2), 0, 0, 1)
#endif
However, that's just an example. You really don't want to be doing this sort of thing all over the place, so I'd certainly stick to simply using CGFloat(<whatever POSIX double value you need>) to get either a 32- or 64-bit value depending on the target architecture.
Apple have added much more help for dealing with different floats in later compiler releases—for example, in early betas you couldn't even take floor() of a single-precision float easily, whereas now (currently Xcode 6.1) there are overrides for floor(), ceil(), etc. for both float and double, so you don't need to be fiddling with conditional compilation.
There seems to be issues currently with automatic conversions between Objective C numeric types and Swift types. For this I was able to get it to work by marking the lineWidth to the Float type. I don't know why they didn't have that issue in the video, I assume that is a different build they were using. Either there is an Objective C interop setting I'm missing, or it's just a beta issue.
To verify some of the basic issues (even happening in Playground) I used:
var x:NSNumber = 1
var y:Integer = 2
var z:Int = 3
x += 5 //error
y += 6 //error
z = z + y //error
For Swift 1.2 you have to cast second parameter to CGFloat
This code works:
ringLayer.transform = CATransform3DRotate(ringLayer.transform, CGFloat(-M_PI/2), 0, 0, 1)