Odd xcode error when calling defined func in Swift - ios

I have the following function defined in a .swift file in a new project I'm creating:
func createCircle(xPos: Int, yPos: Int) {
// do code here
}
For some reason when I try to call it using the following code xcode displays an error stating "Missing argument label 'yPos:' in call".
createCircle(100, 100)
The odd thing is it treats yPos different than xPos - if I include xPos: in the calling function it highlights the line and says "Cannot convert the expression's type '$Tf' to type 'IntegerLiteralConvertable'". So the following is what I end up with in order to call the aforementioned function:
createCircle(100, yPos: 100)
Am I missing something obvious or is this an xcode beta bug?

According to the Swift documentation
Section - Methods - Local and External Parameter Names for Methods
"Specifically, Swift gives the first parameter name in a method a
local parameter name by default, and gives the second and subsequent
parameter names both local and external parameter names by default."
Judging from your error, it seems like you're using a method and not a function. You don't need to provide the name for the first parameter but you must for subsequent parameters but this behaviour can be changed with the _ (underscore character).
class MyCircle {
var xPos: Double = 0.0;
var yPos: Double = 0.0;
func createCircle(x: Double, _ y: Double) {
// insert create circle logic here.
}
}
var cir = MyCircle();
cir.createCircle(100, 100);
By using the underscore for subsequent parameters you don't have to provide the label for them when calling the method.

Related

How can I make an UIImageView change depending on the chosen number?

I'm creating an app which chooses two random cards out of a 52-card deck. Then, if one of the card is strong (in my case, strong cards are "10" or stronger) I want it to show an image "yes" (tick). If both of the cards are weak, then I want it to show an image "no" (cross). I've been trying to find a problem, but every time I change something, a new type of error occurs.
I tried to set an unknown output type in func resultOfShuffle, I tried creating and naming an outlet for my UIImageView couple of times.
let cardArray = ["1.png", (...), "52.png"]
// All of the cards, from 2 to Ace (with every color). Number "33" is a card 10.
...
let cardResults = ["yes.png"]
...
#IBOutlet weak var theResult: UIImageView!
...
func randomizeCards() {
chooseCardOne = Int.random(in: 0 ... 51)
chooseCardTwo = Int.random(in: 0 ... 51)
...
func resultOfShuffle(firstCard : Int, secondCard : Int) -> UIImageView {
if firstCard > 33 {
return theResult.image = UIImage(named: cardResults)
}
}
And now, the return of the last func resultOfShuffle is wrong - telling me: Use of unresolved identifier 'theResult'. I also tried to find the solution to this problem, but it is kinda tricky and I don't get it.
That's how my app looks like:
https://imgur.com/a/kjdcqcO
Is every statement executed in the same ViewController?
It should recognize theResult as a UIImageView, then.
Update
The problem is, as solved in the comments, based on the scope of the function declaration. Since it is declared outside of the class where theResult is defined, it can't get access to it.
The solutions could be passing the variable as an argument to the function, or declaring the function in the same scope of the variable - inside the ViewController.
Other notes
You are, anyway, trying to return something with this line:
theResult.image = UIImage(named: cardResults)
which doesn't evaluate to a type, but simply sets the image of the view to what's in cardResults. Therefore, you shouldn't return anything, but merely using this function in order to update the content of the view - this means you should use a Void return type.
Furthermore, you are passing to the image initializer a [String] type, while you should just pass a String.
Try something like this:
func resultOfShuffle(firstCard : Int, secondCard : Int) {
if firstCard > 33 {
theResult.image = UIImage(named: cardResults[0])
}
}

Syntax to Call Swift Extension Function from Objective-C

I have a project with both objective-c and swift. Everything is hooked up properly so I can generally call extensions on classes without issue. In this case, however, I have to pass an argument to the extension and am getting hung up on the syntax.
Here is the Swift 3 Extension
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
From Swift you can call it with
let x = Double(0.123456789).rounded(toPlaces: 4)
The following is not working in Objective-C: I have played around with it but can't get the correct syntax:
double test = 0.123456789;
double roundedtot = test.roundedToPlaces:2;
The specific error is
'Member reference base type 'double' is not a structure or union'
which I gather is a c error but since you can call the function in swift it seems there ought to be a way to call it in Objc-C
You need to add #objc to the extension definition in order to call it from Objective-C.
Also, it's important to note that only extensions for classes (not for structs or enums) are accessible from Objective-C.

Can someone explain this Swift function to me? [duplicate]

Example:
mutating func moveByX(deltaX: Double, y deltaY: Double)
The first parameter takes a Double and saves it in that method scope as deltaX. However, what are y and deltaY?
I read this and can't find anything about it: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Methods.html
This is how Swift mimics Objective C's named parameters (pseudo naming of arguments). Its pretty easy to break down.
mutating func moveByX(deltaX: Double, y deltaY: Double)
1 2 3 4 5 6
Beginning of method name
First parameter name
First parameter type
Second part of method name
Second parameter name
Second parameter type
In this example, the method is actually called moveByX:y: The equivalent Objective C method definition would look like this.
- (void)moveByX:(Double)deltaX y:(Double)deltaY
When calling this method, the second part of the name is included alone with the rest of the arguments.
var dub = Double(0.5)
moveByX(dub, y: dub)
In your example,
y is the external parameter name,
deltaY is the local parameter name, and
Double is the type of the parameter.
If you are familiar with Objective-C, this corresponds to a method with the following declaration:
-(void)moveByX:(double)deltaX y:(double)deltaY;
Methods in swift have both an external parameter name and a local parameter name. External is defined first then external, if only one is defined swift compiler puts in the defaults.
Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both local and external parameter names by default.
In the example, "y" is the external parameter used when calling the method, "deltaY" is the variable name used in the internal calculations of that function.
You can also use _ to signify that you don't want a parameter to have an external name.
# is used for shorthand when both your external and internal name are the same.
Examples
1)
func exampleFunction(externalVarName1 localVarName1: Int, externalVarName2 localVarName2: Int) {}
is called like this:
exampleFunction(externalVarName1: 0, externalVarName2: 0)
2)
func exampleFunction2(autocompleteHintName: Int, autocompleteHintName2: Int) {}
is called like this
exampleFunction2(0, 0)
3)
func exampleFunction3(#nameForBoth: Int, #nameForBoth2: Int) {}
is called like this
exampleFunction3(nameForBoth: 0, nameForBoth2: 0)
4)
func exampleFunction4(nameForBoth nameForBoth: Int, nameForBoth2 nameForBoth2: Int) {}
is the same as 3) but throws a warning that the # shorthhand can be used. called like this
exampleFunction4(nameForBoth: 0, nameForBoth2: 0)
5)
func exampleFunction5(_: Int, _: Int) {}
is called like this
exampleFunction5(0, 0)
deltaX and deltaY are the parameter names when you are writing the function. However, when you call the function it will be called as movebyX(val, y: val) where val is replaced by the Double you are passing into the function. The y in the middle is essentially to help the readability of the function when it is called and is common practice in swift to make your code as readable as possible (the person calling your function can easily tell what each parameter is without looking at the function header).

annoying parameter error for polylineWithCoordinates

I am trying to initialize a polyline from a 2 element CLLocationCoordinate2D array called coordarray and the number 2, using this code:
self.line = MKPolyline.polylineWithCoordinates(coordarray,2)
however I am getting an error saying
Cannot invoke 'polylineWithCoordinates' with an argument list of type
([CLLocationCoordinate2D],Int)
I have checked the docs, and it seems that I have passed the correct parameter list, what am I missing?
That error message is very misleading - checking the documentation for MKPolyline there isn't actually a static method called polylineWithCoordinates for Swift, you may be looking at the Objective-C version of the documentation*. Perhaps you meant to use:
convenience init!(coordinates coords: UnsafeMutablePointer<CLLocationCoordinate2D>,
count count: Int)
In which case I believe your code needs to be:
// Note - coordarray is declared as var
var coordarray = // ...
self.line = MKPolyline(coordinates: &coordarray, count: 2)
Here's a link detailing more about adding an MKPolyline overlay: http://mobiletoolworks.com/adding-a-mkpolyline-overlay-using-swift-to-an-ios-mapkit-map/
*To change the documentation from displaying Objective-C to Swift, there's a control in the top-right corner of the page:

Swift: syntax explanation - round brackets then "in"

I following tutorial and confused with following code:
let rectToDisplay = self.treasures.reduce(MKMapRectNull){
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in
let treasurePointRect =
MKMapRect (origin: treasure.location.mapPoint, size: MKMapSize (width: 0, height: 0))
return MKMapRectUnion(mapRect, treasurePointRect)
}
In fact, I'm not understand only that line:
(mapRect: MKMapRect, treasure: Treasure) -> MKMapRect in
Is that some kind of function or something? What is the output? Im not quite understand meaning of that construction (struct: struct, someClass: someClass) -> Struct in
What is that logic? What is the meaning of "in"?
If you wondering, treasure is custom class that contain coordinate properties - latitude, longitude, etc.
I understand the "whole" meaning of that code snippet, but syntax of that line confuse me a bit..
Could you provide an explanation? Thanks a lot!
In Swift there are two ways to declare a function: with func, and with a closure expression:
// this is a function that takes an Int and returns a String
func f(i: Int) -> String { return i.description }
f(1) // returns "1"
// this is also a function that takes an Int and returns a String
let g = { (i: Int) -> String in return i.description }
g(1) // returns "1"
The latter is a closure expression – a quick way of defining a new function inline. They are most commonly used with functions that take functions (for example map, which takes an array and a function that transforms an element of that array, and runs the function on each element creating another array).
The syntax for closure expressions is they start, within braces, with arguments and return type, and then an in, and then the function body. Unlike with func, which starts with the func keyword, then the arguments and return type, followed by the function body within braces.
You don't always see the in because it can be left off. There are lots of shorthands that allow you to skip the arguments and return type (and the return keyword) altogether. But sometimes you need to give them, and then you need the in keyword.
You can read more about closure expressions in the Apple Swift book. You can read more about functions and closure basics here.

Resources