使用“where”子句在Swift算术中生成可选类型

时间:2016-06-03 03:00:04

标签: ios swift uiscrollview where

我想在用户交互期间触发基于某些UI关系的条件逻辑(在这种情况下,我想在用户滚动到UIScrollView中的某个点时调用方法)。我希望以下代码行能够合法地执行此操作,因为它具有很强的表现力:

func scrollViewDidScroll(scrollView: UIScrollView) {
    guard let overlap = scrollView.contentOffset.y - 220 where overlap > 0 else {
        return
    }

    reactToScrollOverlap(of: overlap)
}

但是,我收到guard let需要可选类型的错误。这是合理的,但我预计在这种情况下where子句会自然地引入一个可选项,因为如果算法运算错误则没有overlap的匹配值。

是否有办法使用guard let(或者,if let),以便包含where子句规定Int,CGFloat或其他原语之间算术结果的条件原始类型?

3 个答案:

答案 0 :(得分:3)

guardif let语句通常仅用于解包选项。我对此解决方案并不十分兴奋,但您可以将scrollView.contentOffset.y转换为Optional<CGFloat>以获得您想要的行为:

guard let overlap = scrollView.contentOffset.y - 220 as CGFloat? where overlap > 0 else {
    return
}

答案 1 :(得分:3)

guard let value = someOptionalValue {
}

if let value = someOptionalValue {
}

这些是将变量绑定到变量的方式。如果您使用guard letif let,则仅用于从可选类型中获取值。

仅当所有选项的值都在where子句之前时,才会触发

和where子句。

我认为你想要做的是这样的事情:

let delta = scrollView.contentOffset.y - 220

if delta > 0 {

} else {

}

我希望清晰而简洁。

修改

我认为这是一种更好的方法:

let yOffset        = scrollView.contentOffset.y
let newOffset:Int? = yOffset > 220 ? yOffset : nil

答案 2 :(得分:2)

你在一个表达式中做了3件事 - 声明一个变量(常量),分配它并检查它的值。

通常不赞成在表达式中声明变量,Swift并没有真正启用它。有一个例外 - 打开期权。您没有展开可选项,因此只需将表达式正确地拆分为声明和比较:

let overlap = contentOffset.y - 220

guard overlap > 0 else {
    return
}

另一种选择是使用case let模式。我不是它的忠实粉丝,但它可能是你想要的:

guard case let overlap = contentOffset.y - 220 where overlap > 0 else {
    return
}

print("overlap:", overlap)