Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Translating ObjC-Blocks to Swift Closures

I am trying to translate some objective-C Code into Swift. I added the Cocoapod "Masonry" for Autolayout to my project and added a Bridging-Header in order to able to use Objective-C Methods in Swift.

This ObjC Method:

[_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(self.view);
}];

should be something like the following Closure:

tableView.mas_makeConstraints({ (make : MASConstraintMaker!) -> Void? in
    make.edges.equalTo(self.view)
})

But I am getting an "Could not find member 'mas_makeConstraints'" which is not the error, as the method is indexed and autocomletion gives me the following:

tableView.mas_makeConstraints(block: ((MASConstraintMaker!) -> Void)?)

?!

Am I doing something wrong here?

like image 693
3vangelos Avatar asked Jun 30 '14 16:06

3vangelos


2 Answers

Just my 2 cents if anyone encounter this case:

This objc

[productView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.equalTo(self.view.mas_left).with.offset(15);
    make.right.equalTo(self.view.mas_right).with.offset(15);
    make.top.equalTo(self.view.mas_top).with.offset(15);
    make.height.equalTo(productView.mas_width);
}];

will turn into

productView.mas_makeConstraints{ make in
    make.left.equalTo()(self.view.mas_left).with().offset()(15)
    make.right.equalTo()(self.view.mas_right).with().offset()(-15)
    make.top.equalTo()(self.view.mas_top).with().offset()(15)
    make.height.equalTo()(productView.mas_width)
    return ()
}
like image 84
L N Avatar answered Nov 15 '22 21:11

L N


This piece here in the method signature:

(block: ((MASConstraintMaker!) -> Void)?)

...is telling you that the block argument is Optional, not the return value, which should be Void (not Void?, where you write (make: MASConstraintMaker!) -> Void?)

also: because Swift Type Inference you don't need to put the types in the block

also also: because Swift Trailing Closures you don't need to put a closure that is the final argument to a method inside of the argument list in parens (and since here it's the only argument, you can leave off the parens entirely)

so really your entire method call with block argument could be re-written as:

tableView.mas_makeConstraints { make in
    make.edges.equalTo(self.view)
}

finally: it looks like the instance method you are calling on make.edges returns a block, and thanks to the Swift convenience feature of 'implicit return of single expression blocks' it's may be the case that your block is implicitly returning the value of that expression when it is expecting Void - so in the end, if the above doesn't work you may still need to explicitly return Void by writing your method call as:

tableView.mas_makeConstraints { make in
    make.edges.equalTo(self.view)
    return ()
}
like image 37
fqdn Avatar answered Nov 15 '22 19:11

fqdn