Swift: Run code when object is within an area - ios

I'm making a true or false game where the we have to determine if the logical expression is true or false. It's a one click game. If we click, the current true condition changes to false and vice versa. A series of logical expression will pop down the screen and when it reaches the zone, the current condition must equal to the logical expression to get a score. To verify the truth value, it checks the image of the truth value. I tried one case, where it is 'true and true' and the current condition is true, which is true. However, when it passes through the zone, the score did not increase. Where did I go wrong?
#IBAction func button_clicked(sender: UIButton) {
if (truth_click == true) {
truth_click = false
self.truth_button.image = UIImage(named: "false_button")
}
else if (truth_click == false) {
truth_click = true
self.truth_button.image = UIImage(named: "true_button")
}
}
func check_truth() {
if (truth_click == true) {
//when it reaches the zone
if (left_truth.center.y > 330 ) {
//if true and true
if ((left_truth.image == UIImage(named: "true")) && (symbol.image == UIImage(named: "and")) && (right_truth.image == UIImage(named: "true"))) {
self.score += 1
}
//if true and false
//if false and true
//if false and false
self.score_label.text = String(self.score)
}
}
if (truth_click == false) {
//when it reaches the zone
if (left_truth.center.y > 330 ) {
//if true and false
if ((left_truth.image == UIImage(named: "true")) && (symbol.image == UIImage(named: "and")) && (right_truth.image == UIImage(named: "false"))) {
self.score += 1
}
//if true and true
//if false and true
//if false and false
self.score_label.text = String(self.score)
}
}
}

Part of your problem is testing *_truth.image against new instances of UIImage(named:...). UIImage is an object. Instantiating a new UIImage creates a new object. Two objects with the same content are not equal ...without extra work.

Related

How to fix conditional binding have optional type not 'Bool'?

how can I solve this problem?
Ive been getting the same error in 10 different places, I have been running tests on it and can't seem to figure this
thanks in advance for any help that you guys provide it really means a lot to me
Initializer for conditional binding must have Optional type, not 'Bool'
extension HomeController: FiltersViewControllerDelegate{
func query(withCategory jewelry: Bool, shoe: Bool, hat: Bool, apearel: Bool, gear: Bool) -> Query {
if jewelry == false && shoe == false && hat == false && apearel == false && gear == false {
stackViewHeightConstraint.constant = 0
activeFiltersStackView.isHidden = true
} else {
stackViewHeightConstraint.constant = 44
activeFiltersStackView.isHidden = false
}
var filtered = baseQuery
// Sort and Filter data
if let jewelry = jewelry, !jewelry.isEmpty { //Error
filtered = filtered.whereField("category", isEqualTo: jewelry)
}
//......more Filters....\\
if let gear = gear, !gear.isEmpty { //Error
filtered = filtered.whereField("category", isEqualTo: gear)
}
return filtered
}
func controller(_ controller: FilterViewController,
didSelectCategory jewelry: Bool,
shoe: Bool,
hat: Bool,
apearel: Bool,
gear: Bool) {
if jewelry == false && shoe == false && hat == false && apearel == false && gear == false {
stackViewHeightConstraint.constant = 0
activeFiltersStackView.isHidden = true
} else {
stackViewHeightConstraint.constant = 44
activeFiltersStackView.isHidden = false
}
let filtered = query(withCategory: jewelry, shoe: shoe, hat: hat, apearel: apearel, gear: gear)
if let jewelry = jewelry, ! jewelry.isEmpty { //Error
jewelryFilterLbl.text = "Jewelry"
jewelryFilterLbl.isHidden = false
} else {
jewelryFilterLbl.isHidden = true
}
//......more Filters....\\
if let gear = gear, !gear.isEmpty { //Error
gearFilterLbl.text = "gear"
gearFilterLbl.isHidden = false
} else {
gearFilterLbl.isHidden = true
}
query = filtered
}
}
Remove .isEmpty check it's not a property of a Bool
if jewelry { //Error
filtered = filtered.whereField("category", isEqualTo: jewelry)
}
//......more Filters....\\
if gear { //Error
filtered = filtered.whereField("category", isEqualTo: gear)
}
You're using if let binding on variables that are not optionals.
For example, your jewel variable is a Bool, not a Bool?. Using optional binding doesn’t make any sense.
if let jewelry = jewelry, ! jewelry.isEmpty { // Jewelry isn't an Optional!!!
jewelryFilterLbl.text = "Jewelry"
jewelryFilterLbl.isHidden = false
} else {
jewelryFilterLbl.isHidden = true
}
Plus, as other users have stated, Bool variables don't have .isEmpty method. Revise your logic and your code, it doesn't work at all.

Get the content of an array of labels in Swift

I'm trying to check the content of an array of labels but it not works.
To explain the program: I have 4 arrays of 4 UIlabels each one and every label contains a number in String. This function returns true if one label contains the number 16. I tried to use the function "contains" but it doesn't work because "16" it's a string and not a label.
Thanks
Example of declaration of array of labels:
Fila1 = [UILabel]()
Function Win:
func win() -> Bool {
for i in 0..<Fila1.count {
if(Fila1[i].text == "16") {
return true
} else if(Fila2[i].text == "16") {
return true
} else if(Fila3[i].text == "16") {
return true
} else if(Fila4[i].text == "16") {
return true
} else {
return false
}
}
return false
}
The issue is that you shouldn't have that else statement return false.
It should be:
if(Fila1[i].text == "16") {
return true
} else if(Fila2[i].text == "16") {
return true
} else if(Fila3[i].text == "16") {
return true
} else if(Fila4[i].text == "16") {
return true
} // end if here
You're exiting out of the loop too early. If the first element isn't what you are looking for you aren't checking the rest.
Your code is fine, you just need to remove the else condition that contains return false and the code should work as expected.

I am not sure why my else if is not being called in my IBAction

I have created an IBAction that handles 2 buttons, first one's title is "True" and the second one's title is "False", when tapped they should display a label however the else if never gets called.
#IBAction func trueOrFalse(sender: UIButton) {
if sender.currentTitle == "True" {
answerR.hidden = false
answerW.hidden = true
} else if sender.currentTitle == "False" {
print("hi")
answerW.hidden = false
answerR.hidden = true
}
}
answerW and answerR are the labels.
I am not sure why, I have tried a couple of things like using taps but I can not seem to figure it out.
Sounds like one of your buttons isn't registering the IBAction - double check and make sure each are connected via Touch Up Inside. If they are connected w/ a different method it may not register as you expect!
You should use button tags. It is very simple like below:
Firstly, you should set each button tag like below:
Buton1 Tag = 0
Buton2 Tag = 1
Then use below code:
#IBAction func trueOrFalse(sender: UIButton) {
if sender.tag == 0 {
answerR.hidden = false
answerW.hidden = true
}else
{
print("hi")
answerW.hidden = false
answerR.hidden = true
}
}
you need to eliminate optional that comes with string
#IBAction func trueOrFalse(sender: UIButton) {
if (sender.currentTitle!)! == "True" {
answerR.hidden = false
answerW.hidden = true
} else if (sender.currentTitle!)! == "False" {
print("hi")
answerW.hidden = false
answerR.hidden = true
}
}

Prime number checker returns the same result each time

I'm a beginner programmer learning Swift and made a basic prime number checker. No matter what it will only give one result, instead of changing based on wether or not the number is prime. Any help would be appreciated.
#IBAction func primeCheck(sender: AnyObject) {
var numberInt = number.text.toInt()
var isPrime = true
if number != nil {
if numberInt == 1 {
isPrime = false
}
if numberInt != 1 {
for var i = 2; i < numberInt; i++ {
if numberInt! % i == 0 {
isPrime = false
} else {
isPrime = true
}
}
}
}
if isPrime == true {
result.text = "\(numberInt!) is a prime number!"
} else {
result.text = "\(numberInt!) is not a prime number!"
}
}
I have another possible solution. At first I divide by two because it cannot be a prime number. Then you loop until the number is prime or the number divided by two is less than the divider.
#IBAction func primeCheck(sender: AnyObject) {
var numberInt = number.text.toInt()
var isPrime = true
var divider = 3
if number < 2 || (number != 2 && number % 2 == 0) {
isPrime = false
}
// you only have to check to half of the number
while(isPrime == true && divider < number / 2){
isPrime = number % divider != 0
divider += 2
}
if isPrime == true {
result.text = "\(numberInt!) is a prime number!"
} else {
result.text = "\(numberInt!) is not a prime number!"
}
}
The error in your logic comes in this section:
if numberInt! % i == 0 {
isPrime = false
} else {
isPrime = true
}
At the top of your function, you initialize isPrime to be true, so in your loop you only need to look for cases that prove the number is not prime. You don't ever need to set isPrime = true again, so just drop the else condition:
if numberInt! % i == 0 {
isPrime = false
}
You actually have two functions here. One to check if a number is prime and the other to display the result. Separating these makes everything much easier to manage.
// function to check primality and return a bool
// note that this can only accept a non optional Int so there is
// no need to check whether it is valid etc...
func checkNumberIsPrime(number: Int) -> Bool {
// get rid of trivial examples to improve the speed later
if number == 2 || number == 3 {
return true
}
if number <= 1 || number%2 == 0 {
return false
}
// square root and round up to the nearest int
let squareRoot: Int = Int(ceil(sqrtf(Float(number))))
// no need to check anything above sqrt of number
// any factor above the square root will have a cofactor
// below the square root.
// don't need to check even numbers because we already checked for 2
// half the numbers checked = twice as fast :-D
for i in stride(from: 3, to: squareRoot, by: 2) {
if number % i == 0 {
return false
}
}
return true
}
// function on the button. Run the check and display results.
#IBAction func primeCheck(sender: AnyObject) {
let numberInt? = numberTextField.text.toInt() // don't call a text field "number", it's just confusing.
if let actualNumber = numberInt {
if checkNumberIsPrime(actualNumber) {
resultLabel.text = "\(actualNumber) is a prime number!" // don't call a label "result" call it "resultLabel". Don't confuse things.
} else {
resultLabel.text = "\(actualNumber) is not a prime number!"
}
} else {
resultLabel.text = "'\(numberTextField.text)' is not a number!"
}
}
It makes it all much easy to read and maintain.
You have to break out of the loop after you find that the number is divisble by another number. Also for prime check you only have to check the divisibility till the square root of the number.
You can also use optional binding to extract numberInt and check for nil. That's the swift way.
#IBAction func primeCheck(sender: AnyObject) {
var isPrime = true
if let numberInt = number.text.toInt() {
if numberInt == 1 {
isPrime = false /
}
else // Add else because you dont have to execute code below if number is 1
{
if numberInt != 1 {
for var i = 2; i * i <= numberInt; i++ { // Only check till squareroot
if numberInt % i == 0 {
isPrime = false
break // Break out of loop if number is divisible.
} // Don't need else condition because isPrime is initialised as true.
}
}
}
if isPrime {
result.text = "\(numberInt) is a prime number!"
} else {
result.text = "\(numberInt) is not a prime number!"
}
}
}
Reason for square root check : Why do we check up to the square root of a prime number to determine if it is prime?
You can refine the code further by refactoring the prime check into a separate function.
func isPrime(number:Int) -> Bool
{
if number == 1 {
return false
}
else
{
if number != 1 {
for var i = 2; i * i <= numberInt; i++ {
if numberInt % i == 0 {
return false
}
}
}
}
return true
}
#IBAction func primeCheck(sender: AnyObject) {
if let numberInt = number.text.toInt() {
if isPrime(numberInt) {
result.text = "\(numberInt) is a prime number!"
} else {
result.text = "\(numberInt) is not a prime number!"
}
}
}
Well i don't know about swift, but maybe this is wrecking your code:
if numberInt! <<
To do a faster algorithm you could just search for divisors from 2 to sqrt(numberInt). (Theorem)

Boolean with swift

This is really confusing. Does anyone have any ideas?
let viewHasMovedToRight == false //initially I want this to be false
then
func moveViewToRight(sender: UIButton!) {
if viewHasMovedToRight == false {
viewHasMovedToRight == true;
UIView.animateWithDuration(
0.75,
animations: {},
completion: { (value: Bool) in
println(" moved")
}
)
}
else {
viewHasMovedToRight == false;
UIView.animateWithDuration(
0.75,
animations:{},
completion:{ (value: Bool) in
println("not moved")
}
)
}
// println("move view")
}
Only the first if is called.
I cannot re-assign the value back to true...
Something that was so easy on Obj-C now with swift is so frustrating...
You have two problems.
One, you are using == (which tests for equality) where you should be using = (which assigns a value). Two, you are declaring a constant and then trying to assign a new value to it later. You need to declare a variable.
var viewHasMovedToRight = false
...
viewHasMovedToRight = true
Also, most people would find this if condition more understandable:
if !viewHasMovedToRight {
And it would be even simpler if you were to reverse the order of your if clauses:
if viewHasMovedToRight {
viewHasMovedToRight = false
...
} else {
viewHasMovedToRight = true
...
}
let viewHasMovedToRight = false not let viewHasMovedToRight == false
EDIT: It looks like you use == instead of = everywhere you are setting the boolean.
#George,
you should use set operator
let viewHasMovedToRight = false
not comparison operator
let viewHasMovedToRight == false
Newbie here.
I used to do that mistake all the time, using = both for assign and to compare.
Use = to assign and == to compare

Resources