Amit
Amit

Reputation: 4896

CGSize is not accepting `.zero`. Ambiguous use of 'init(width:height:)'

In UICollectionViewDelegateFlowLayout when I am using:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: 0, height: 0)
}

It works fine.

But when I am trying :

CGSize(width: .zero, height: .zero)

It shows an error as:

Ambiguous use of 'init(width:height:)'

In fact :

CGSize(width: .zero, height: 0)

also works. It just adding both as .zero is not working.

Upvotes: 1

Views: 1438

Answers (2)

Rob Napier
Rob Napier

Reputation: 299345

CGSize.init(width:height:) has three versions: Double, CGFloat, and Int. All three of those have a .zero static method as well. So when you pass (.zero, .zero), Xcode doesn't know which version to call.

When you pass 0, that's an integer literal. Anything that conforms to ExpressibleByIntegerLiteral can be initialized using that. That includes all the Int and UInt types (UInt8, Int16, etc), but also the floating point types (Float, Double), Foundation types like NSNumber, and even MaterialScalarParameter out of RealityKit. But Swift favors Int. For example:

let x = 0

Here, x is Int, even though this is technically ambiguous. Swift usually doesn't like to favor one type over another, but it has special cases for literals. It doesn't have special cases for static methods like .zero, though.

So for CGSize(width: 0, height: 0), it uses the Int version because you pass integer literals. CGSize(width: .zero, height: 0), also uses the Int version because the height parameter is a literal and Int.zero exists, so it works. But for CGSize(width: .zero, height: .zero), Swift doesn't know which .zero to call.

Upvotes: 4

vadian
vadian

Reputation: 285072

The syntax

CGSize(width: .zero, height: 0)

is not recommended anyway even if it works.


.zero is a static variable of CGSize and can be used properly

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize.zero
}

or even

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return .zero
}

Upvotes: 4

Related Questions