I am trying to create an extension method on NSLayoutAnchor to accept a multiplier. I get a weird Swift compile error (Swift 3, XCode 8.2.1) not in the extension file but in the corresponding .h file (this file is automatically generated by the compiler) for the module:
@interface NSLayoutAnchor (SWIFT_EXTENSION(MYMODULENAME))
- (NSLayoutConstraint * _Nonnull)constraintTo:(NSLayoutAnchor</* AnchorType */> * _Nonnull)anchor multiplier:(CGFloat)m;
@end
The error points to /* AnchorType */
and says: "Expected a type". Well, that makes sense since /* AnchorType */
is not a type but a comment. However I am using the AnchorType
type parameter in the method signature.
The extension source code is as follows:
extension NSLayoutAnchor {
open func constraint(to anchor: NSLayoutAnchor<AnchorType>, multiplier m: CGFloat) -> NSLayoutConstraint {
// ...
}
}
NOTE: Fixed as of Swift 4, see benrudhart's answer below.
This is currently an issue with swift and objc. Extending objc generics in swift then bridging back into objc is not allowed. Even adding a @nonobjc
doesn't fix the issue. Take a look at the bug filed here: https://bugs.swift.org/browse/SR-2708 for more info.
A potential fix is to make an extension on each concrete type of NSLayoutAnchor
. The concrete types are NSLayoutXAxisAnchor
, NSLayoutYAxisAnchor
and NSLayoutDimension
.
extension NSLayoutDimension {
open func constraint(to anchor: NSLayoutDimension,
multiplier m: CGFloat) -> NSLayoutConstraint
}
extension NSLayoutXAxisAnchor {
open func constraint(to anchor: NSLayoutXAxisAnchor,
multiplier m: CGFloat) -> NSLayoutConstraint
}
extension NSLayoutYAxisAnchor {
open func constraint(to anchor: NSLayoutYAxisAnchor,
multiplier m: CGFloat) -> NSLayoutConstraint
}