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

1.2k views Asked by At

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.

2

There are 2 answers

0
vadian On BEST ANSWER

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
}
0
Rob Napier On

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.