Extra argument "named" in call - ios

#IBAction func rerollTapped(sender: UIButton) {
var pickupLines:[String] = [
"aye babe, you from iraq cause you should babhdad ass up",
"HBB asdjksja asjd aj iueihieu",
"Dollar Menu akjshdskjhdksj",
"askdjkjashkjhd",
"skajshdkasjhdka"
]
var randomPickupLine = arc4random_uniform(UInt32(pickupLines.count))
self.pickupLabel.text = UILabel(named: randomPickupLine)
I'm attempting to randomize pickup lines and display the random line in a label. When the Re-roll button is tapped the next random pickup line is shown in the label.
It seems the problem is with this last line, it says "Extra argument "named" in call"
Any thoughts?

UILabel doesn't have an init method that takes a name (initWithName: in Objective-C) so that's why that is an "extra argument" (to the init() method). Perhaps you were thinking of UIImage?
Also, your randomPickupLine is a number (the index), not the string value.
Also, you are trying to assign label (a UI element) to the text property of another label (which expects a String)

Related

Is there a way to append a string to an array of strings in swift from an IBAction of UISwitch in swift?

I am building a Password Generator app, and I want to add the feature that the user can choose between generating a password with symbols in it such as: "!", "#", "&", ect. I want to do that with a UISwitch.
The problem is that I have an array of strings inside of a function (Inside the function I have all the code the make the generator work). Just like showed in the following picture:
And I have an IBAction of UISwitch, I tried appending a string with an if statement. Just like in the following screenshot:
But it just does not work.
I am new to swift so could someone help me with this problem? Thanks!
Couple of things. First, your words array is defined inside the generatePassword method. So it can only be used within that method. That's why you're getting the error when trying to access it from another method (switchSymbols).
To fix that, declare your words array as a class member.
class ViewController: UIViewController {
var words = ["A", "B", "C", "D"]
#IBAction func switchSymbols(_ sender: UISwitch) {
if sender.isOn {
words.append(contentsOf: ["!", "#", "$", "&"])
}
print(words)
}
}
Now every method within this view controller can access that array.
Second, notice how I changed the words array to a var from a let. let means it's a constant. Member declared as let cannot be changed after later. So you won't be able to append elements to it. When you define it as a var (variable), you can.
Third, see that I'm using the append(contentsOf:). The append(_:) method only adds a single element to an array. But in your code, you're adding another array directly to the words array. To add contents of one array to another array, you use the append(contentsOf:) method.

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])
}
}

How to retrieve variable data from a label in UI tests

This is what I have so far and I am simply trying to get the result that is output in a label and test it against set results:
func testExample() {
let app = XCUIApplication()
let enterRomanNumeralsHereTextField = app.textFields["Enter roman numerals here"]
enterRomanNumeralsHereTextField.tap()
let convertButton = app.buttons["Convert"]
//1
enterRomanNumeralsHereTextField.typeText("LL")
convertButton.tap()
XCTAssertTrue(app.staticTexts.element(matching:.any, identifier: "Roman Numerals").label == "NotValidRomanNumber")
//2
enterRomanNumeralsHereTextField.typeText("LXXXIX")
convertButton.tap()
XCTAssertEqual(app.otherElements.containing(.staticText, identifier:"Roman Numerals").element.value as! String, "89")
//3
enterRomanNumeralsHereTextField.typeText("")
enterRomanNumeralsHereTextField.typeText("LXXVIII")
convertButton.tap()
XCTAssertEqual(app.otherElements.containing(.staticText, identifier:"Roman Numerals").element.value as! String, "")
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
The first attempt(labeled 1) gives me a build error saying "cannot call value of non function type XCUIElement.
The second attempt builds but the test fails because even though the label does indeed produce the right value, the test is reading the label as blank which brings us to my third attempt which passes the test because I compared it to a blank label, which is what its showing.
So as I said above I'm just wondering how exactly to retrieve the label value that is a result of a "calculation" or button press.
Unfortunately when a UILabel is accessed in a UITest the XCUIElement's value property is not set with the text property of the UILabel. It is always empty.
XCUIElement also has a label property which you can use for your purpose. You only have to make sure that you are not setting the accessibilityLabel on your UILabel. Use accessibilityIdentifier instead:
In your app:
label.accessibilityIdentifier = "Roman Numerals"
In your UITest:
XCTAssertEqual(app.staticTexts.element(matching:.any, identifier: "Roman Numerals").label, "89")

How to implement functions count and dropLast in swift, IOS?

I am making calculator in Swift. Stuck in backspace button. If user press wrong digit then backspace button would help to delete digit off the display.
Though I wrote dropLast function and works. It return appropriate result. How to use count method, don't understand the return type of count method.
#IBOutlet weak var display: UILabel!
#IBAction func backspace() {
//how to use count method to check collection of elements
//dropLast drop the last digit and display result
let dropedDigit = dropLast(display.text!)
display.text = dropedDigit
}
How about something like this:
private func dropLast(text: String) -> String {
let endIndex = advance(text.endIndex, -1)
return text.substringToIndex(endIndex)
}
It calculates the index where you want to make the cut (endIndex of text - 1) and then returns the substring to this index. This function should drop the last character.
I am not using count method here, but for you reference Swift 1.2 introduces count(<#x: T#>) method that calculates length of sets including Strings.
I know this thread is outdated, but I just went through the process of making this work, myself, in Swift 2.2, and figured I could help answer it.
#IBAction func delButton(sender: AnyObject) {
if display.text != nil {
var tempString = Array(display.text!.characters)
tempString.removeLast(1)
display.text = ""
for num in 0..<tempString.count {
display.text = display.text! + String(tempString[num])
}
}
}
Basically, we're checking to see that the display label has stuff in it, so we don't throw an error, and if so, making a variable in the scope of the function to hold the label's characters individually in a string. After that, we remove the last character from the array, clear out the label to ensure we aren't adding what's already there to our new values, then iterating through the updated array of characters and adding it to the label.
It's important to note that we are casting the values contained in the array as String, because they've been put into the array as character values, which operate differently than the string value the label is expecting.
Like I said, I know the thread is a little out of date, but I've been going through courses in Swift, and have discovered that while there is a plethora of information out there for Objective-C, there is perilously little information out there for how to do a lot of those things in Swift. Since the language is being updated repeatedly, I've noticed a growing divide between the two languages.

Weird error in accessing the text of UIButton in swift

When I write a simple function such as this:
#IBAction func buttonTapped(theButton:UIButton) {
println(theButton.titleLabel.text);
}
It gives me an error: UILabel doesn't have a label called text.
However, when I change it to this:
#IBAction func buttonTapped(theButton:UIButton) {
println(theButton.titleLabel?.text);
}
It works fine, but it prints out something like this:
Optional("1");
What I am doing wrong? I am expecting a value of 1. But it is printing out Optional("1") and secondly, it is working fine when println(theButton.titleLabel?.text);
You can get directly from
let title = theButton.currentTitle!
Optional chaining makes the result optional, so you are printing optional value: https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/OptionalChaining.html
With optional binding you can print the value only if it exits.
if let text = theButton.titleLabel?.text {
println(text)
} else {
// text doesn't have value
}
#Kirsteins's answer shows how to obtain the button label text in a safe manner.
Remember that:
UIButton has a titleLabel, which is an optional UILabel.
UILabel has a text property, which is an optional String
so there are 2 optionals in the chain. You can use optional binding as in #Kirsteins's answer, or use forced unwrapping:
let text = theButton.titleLabel!.text!
which however I discourage using, because if any of the 2 is nil you'll have a runtime exception. But for completeness it's worth mentioning.
The buttons titleLabel property returns an optional UILabel, that means it's possible that the button doesn't have a titleLabel.
var titleLabel: UILabel? { get }
If you don't set a title to the button, then the button doesn't have a titleLabel property, the iOS framework adds the titleLabel only if the button has a title, I think this happens to reduce memory.
This is why you have to put the "?" (is called optional chaining you can read about it here http://bit.ly/1vrSOi1) in that line, but this usually get auto completed by Xcode itself.
Kirsteins answers it correctly but misses one small detail
if your object can be nil (optional) you need to check first if it exists to then access its value, like this:
if let text = theButton.titleLabel?.text {
println(text)
}
but you can also ignore the if and just call it like this:
let text : String = theButton.titleLabel?.text
// If theButton.titleLabel don't exists then text will be nil
this happen if the IBOutlet was declared with ? but if you declare with ! that means you know that it could be nil, but you never want it to be nil, for a IBOutlet i prefer this approach since if the IBOutlet is not connected then maybe something is worn with my code.
#IBOutlet var theButton : UIButton!
// and get text value as
theButton.titleLabel!.text
this will ensure theButton.titleLabel could be nil, but in this part of code it is required, hope this helps to understand the difference between optional (?) and optional required (!)

Resources