Reputation: 2345
Note that I'm not trying to set the value in a CGRect. I'm mystified as to why the compiler is issuing this claim:
let widthFactor = 0.8
let oldWidth = wholeFrameView.frame.width
let newWidth = wholeFrameView.frame.width * widthFactor // Value of type '(CGRect) -> CGRect' has no member 'width'
let newWidth2 = wholeFrameView.frame.width * 0.8 // This is fine.
Upvotes: 2
Views: 347
Reputation:
Because, as others have noted, you can't multiply a Double
and a CGFloat
, the compiler doesn't know what you're intending.
So, instead of giving you an error about the frame property, which you currently think it's doing, it's actually making its best guess*, and giving you an error related to the frame method. No method method has a width
property, so what it tells you is true.
*Of course, its best guess is not good enough, hence a human being coming here to ask a question about it. So please file a bug!
Stepping onto my soapbox: This confusion would be avoided if Apple hadn't named the method the thing it returns. The convention to prefix all such methods with
get
solves the problem. Some convention is important in any language with first-class functions, to disambiguate between properties and methods.
Upvotes: 1
Reputation: 271775
All the dimensions of a CGRect
are of type CGFloat
, not Double
, and because Swift is especially strict about types, you can't multiply a CGFloat
by a Double
.
The interesting thing though, is that both CGFloat
and Double
implement ExpressibleByFloatLiteral
. This means that 0.8
, a "float literal", can be interpreted as either a Double
or a CGFloat
. Without context, it's always a Double
, because of how the compiler is designed. Note that this only applies to float literals like 3.14, 3e8 etc, and not to identifiers of variables.
So the expression wholeFrameView.frame.width * 0.8
is valid because the compiler sees that width
is a CGFloat
, so it treats 0.8
as a CGFloat
as well. No problems.
On the other hand, when you declare the variable widthFactor
, it is automatically given the type Double
, because there aren't any more context on that line to suggest to the compiler that you want it to be any other type.
This can be fixed by directly telling the compiler that you want widthFactor
to be a CGFloat
:
let widthFactor: CGFloat = 0.8
Upvotes: 2
Reputation: 18898
Width is a CGFloat
where your multiplier is a Double
. Explicitly declare the type of your multiplier:
let widthFactor: CGFloat = 0.8
Upvotes: 3
Reputation: 590
wholeFrameView.frame
has no member width
. Also, you need widthFactor
to be of type CGFloat
. Try:
let newWidth = wholeFrameView.frame.size.width * CGFloat(widthFactor)
Upvotes: -4