I would like to trigger conditional logic based around certain UI relationships during user interaction (in this case, I want to call a method when a user scrolls to a certain point in a UIScrollView
). I would expect the following line of code to do this legally, since it is quite expressive:
func scrollViewDidScroll(scrollView: UIScrollView) {
guard let overlap = scrollView.contentOffset.y - 220 where overlap > 0 else {
return
}
reactToScrollOverlap(of: overlap)
}
However, I get the error that the guard let
requires an optional type. That's reasonable, but I expected in this case that the where
clause would naturally introduce an optional, since if the arithmetic works out wrong then there is no matching value of overlap
.
Is there a way to use guard let
(or, alternatively, if let
) such that included where
clauses stipulate conditions on the outcomes of arithmetic between Int, CGFloat, or other primitive/primitive-like types?
guard let value = someOptionalValue {
}
if let value = someOptionalValue {
}
These are the way how you bind an optionals to a variable. If you are using guard let
or if let
you are using to get a value from optional types only.
and where clause will be triggered only when all the optionals have a value that precedes the where clause.
I think what you want to do is something like this:
let delta = scrollView.contentOffset.y - 220
if delta > 0 {
} else {
}
I would prefer clarity over brevity.
Edit:
Here is a better way to do it I think:
let yOffset = scrollView.contentOffset.y
let newOffset:Int? = yOffset > 220 ? yOffset : nil
guard
and if let
statements are normally only used to unwrap optionals. I'm not really thrilled with this solution, but you could cast scrollView.contentOffset.y
as an Optional<CGFloat>
to get the behavior you want:
guard let overlap = scrollView.contentOffset.y - 220 as CGFloat? where overlap > 0 else {
return
}
You are doing 3 things in one expression - declaring a variable (constant), assigning it and checking its value.
Declaring a variable in expressions is usually frowned upon, Swift does not really enable it. With one exception - unwrapping of optionals. You are not unwrapping an optional so just split the expression correctly into a declaration and a comparison:
let overlap = contentOffset.y - 220
guard overlap > 0 else {
return
}
Another option is to use the case let
pattern. I am not a big fan of it but it's probably what you want:
guard case let overlap = contentOffset.y - 220 where overlap > 0 else {
return
}
print("overlap:", overlap)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With