17

我正在尝试从 Objective-C 重写为 Swift,我无法弄清楚语法或理解文档

这是我在 Objective-C 中编写的一个简化示例:

[UIView animateWithDuration:10.0 animations:^{self.navigationController.toolbar.frame = CGRectMake(0,10,0,10);}];

我如何在 Swift 中写这个?

这是模板自动完成给出:

UIView.animateWithDuration(duration: NSTimeInterval, animations: (() -> Void))
4

5 回答 5

16

这是快速关闭格式:

{(parameter:type, parameter: type, ...) -> returntype in
    //do stuff  
}

这是你应该做的:

//The animation closure will take no parameters and return void (nothing).
UIView.animateWithDuration(duration: NSTimeInterval, animations: {() -> Void in
    //Animate anything.
})

这是闭包的文档

于 2014-06-04T13:27:54.083 回答
11

由于动画参数的预期参数类型和返回类型是已知的,编译器可以毫无问题地推断它们。这应该可行(尽管我目前没有可用的游乐场:

UIView.animateWithDuration(10.0, animations: {
  self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
})

有关闭包的更多信息,请参阅swift 文档中的章节

请注意CGRect()-开发人员文档显示CGRect()在 swift 代码中使用。也许它需要进口?

更新评论:您还可以使用尾随闭包,如下所示:

UIView.animateWithDuration(10.0) {
  self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}
于 2014-06-04T13:28:59.327 回答
6

以下代码可以指导您编写自己的块。

class func testFunc(completion: ((list : NSArray!) -> Void)?) {
    //---  block code.
    if completion! != nil {
        completion! (list: NSArray())
    }
}

你可以这样称呼它——

className.testFunc {
(list: NSArray!) -> Void in
}
于 2014-09-30T11:56:59.323 回答
3

您基本上可以用 3 种相同的方式编写它:

在闭包/代码块中写下正确的操作:

UIView.animateWithDuration(10.0) {
  self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}

这也称为尾随闭包(如果闭包参数是最后一个参数,则只能进行尾随闭包)

这并不意味着不再写入参数“动画”。它是写的,但就像上面的格式一样。


准确地写在行内,大多数开发人员避免这样,因为用所有的括号和大括号来写有点麻烦。

UIView.animateWithDuration(10.0, animations: {
  self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
})

(与您写的名称即“动画”的尾随闭包相反)这被称为内联闭包


以更模块化的方式编写

UIView.animateWithDuration(duration: NSTimeInterval, animations: animatingFunc)

func animatingFunc() {
  self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}

记住参数“动画”的类型是() -> Void

就像我们正在做的那样, animatingFunc 不带任何参数,即 '()' 并且不返回任何参数,即 'void'

(在 Swift 中,函数是类型,可以作为参数传入)有些人可能会说这更具可读性,有些人可能会说尾随闭包是......


旁注1 你也可以什么都不做(这真的没有意义,但在许多其他处理程序/动画/完成处理程序中你可能不想做任何事情)

UIView.animateWithDuration(duration: NSTimeInterval, animations: nil)

旁注2

当您必须捕获一个值时,闭包变得更加有趣。看这个简单的演示。有关 Swift 闭包的更多信息,请参阅 Apple 文档

于 2016-12-01T22:41:04.370 回答
2

如何在 Swift 中声明闭包?

  1. 作为变量:

    var closureName: (ParameterTypes) -> ReturnType

  2. 作为可选变量:

    var closureName: ((ParameterTypes) -> ReturnType)?

  3. 作为类型别名:

    typealias ClosureType = (ParameterTypes) -> ReturnType

  4. 作为常数:

    let closureName: ClosureType = { ... }

  5. 作为另一个函数的参数:

    funcName(parameter: (ParameterTypes) -> ReturnType)

注意:如果传入的闭包将超出方法的范围,例如,如果您将其保存到属性中,则需要使用@escaping.

  1. 作为函数调用的参数:

    funcName({ (ParameterTypes) -> ReturnType in statements })

  2. 作为函数参数:

    array.sorted(by: { (item1: Int, item2: Int) -> Bool in return item1 < item2 })

  3. 作为具有隐含类型的函数参数:

    array.sorted(by: { (item1, item2) -> Bool in return item1 < item2 })

  4. 作为具有隐含返回类型的函数参数:

    array.sorted(by: { (item1, item2) in return item1 < item2 })

  5. 作为最后一个函数参数:

    array.sorted { (item1, item2) in return item1 < item2 }

  6. 作为最后一个参数,使用速记参数名称:

    array.sorted { return $0 < $1 }

  7. 作为最后一个参数,带有隐含的返回值:

    array.sorted { $0 < $1 }

  8. 作为最后一个参数,作为对现有函数的引用:

    array.sorted(by: <)

  9. 作为具有显式捕获语义的函数参数:

    array.sorted(by: { [unowned self] (item1: Int, item2: Int) -> Bool in return item1 < item2 })

  10. 作为具有显式捕获语义和推断参数/返回类型的函数参数:

    array.sorted(by: { [unowned self] in return $0 < $1 })

本网站并非旨在详尽列出所有可能的闭包用途。
参考: http: //goshdarnclosuresyntax.com/

于 2020-01-07T07:08:50.937 回答