Swift 4 Expression type '@value CGRect' is ambiguous without more context
Asked Answered
V

13

39

I am trying to implement a animation for a rectangle to perform modal vertical swipe.However, when I try to compile the code I get the following error "Swift 4 Expression type '@value CGRect' is ambiguous without more context". I have isolated the issue to the arguments that is being passed to the CGRect init value, but according the Apple's iOS documentation these parameters should be enough to specify the 'frame' view that I need to animate.

Here is my code:

func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    guard
        let fromView = transitionContext.viewController(forKey: .from),
        let toView = transitionContext.viewController(forKey: .to)

    else {
            return
    }
    let containerView = transitionContext.containerView
    containerView.insertSubview((toView.view)!, belowSubview: (fromView.view)!)

    let toFrame = transitionContext.finalFrame(for: toView)

    let screenBounds = UIScreen.main.bounds

    let bottomLeftCorner = CGPoint(x: 0, y: screenBounds.height)

    let finalFrameForVC = CGRect(origin: bottomLeftCorner, size: screenBounds.size)

    UIView.animate(withDuration: 2, delay: 1,
                   options: [], (using: transitionContext.finalFrame(for: fromView)),
        animations: {
            fromView.view.frame = finalFrameForVC
    },
        completion: { _ in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    })
}
Vigil answered 2/7, 2018 at 16:22 Comment(1)
This problem belongs to data type, I tried to subtract value between CGFloat and Int types, later I converted both in to same type Ex: width: Int((filterView?.filterTblView.frame.width)!)-Int(width!)Rendition
I
43

I had the same error when I tried to multiply view.frame.height by a Double. If you are doing any math on screenBounds properties, make sure the types match.

Improvident answered 24/9, 2018 at 16:20 Comment(0)
T
39

My problem was that I was trying to perform an operation between a CGFloat variable and Double variable.

Fix: Convert the Double variable to CGFloat. Check your variable types.

I hope it helps! :)

Trinee answered 10/1, 2019 at 17:58 Comment(3)
This was my problem as well. What a useless error messageRevenant
Same as yours... The solution is simply putting your "wrong" variable into CGFloat( HERE ).Attenuator
Helping a lot!! In my case I was comparing CGFloat and CGPoint.Globule
P
15

I got here looking for an answer to what was causing the error "Expression type '@lvalue CGRect' is ambiguous without more context", and while nothing here answered this for me I did find the solution to the problem so I'll leave it here for anyone else who stumbles on this question via Google. When creating your CGRect make sure to explicitly cast any ambiguous values to CGFloats (e.g. var width = CGFloat(100)) instead of relying on the compiler to infer the correct type/cast for you.

Prefix answered 23/10, 2018 at 15:41 Comment(1)
Or you could set local variable first and than put it to the function as a parameter. Result- no errors. let viewWidth = view.bounds.width let viewHeight = view.bounds.height scrollView.contentSize = CGSize(width: viewWidth, height: viewHeight)Triangulate
B
9

This is a bug in XCode 10.1 which I am about to report.

let myHeight = CGFloat(100)

myHeight -= myView.frame.height

This produces the error:

"Expression type '@lvalue CGRect' is ambiguous without more context"

The error is wrong, the problem is that myHeight is a constant.

Basifixed answered 18/12, 2018 at 11:56 Comment(1)
any response from Apple?Hob
V
5

For me, I was putting Int as CGRect height.

Xcode was mistakenly pointing to y with this error

Expression type '@value CGRect' is ambiguous without more context

enter image description here

Solution

Just implicitly define the height as CGFloat

let height:CGFloat = 100
Virtuosic answered 4/5, 2019 at 0:4 Comment(1)
@YogeshPatel, Then voting up would be appropriated ;)Virtuosic
P
4

It's not your finalFrameForVC which rise the exception "'@value CGRect' is ambiguous without more context" but it's fromView.view.frame.

Fix it by declaring fromView.view explicitly as UIView :

UIView.animate(withDuration: 2, delay: 1, options: [], animations: {
      let view: UIView = fromView.view
      view.frame = finalFrameForVC as! CGRect
    }) { _ in
      transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    }
Prepotent answered 23/7, 2018 at 10:32 Comment(2)
Yes I know, but the compiler is asking you to specify that it is a UIView. I don't know why :(Prepotent
This worked to me, thanks! It is not an uncommon error of Xcode when it says "too complex expression" and you have to break it into meaningful parts.Lathy
E
2

The problem is your animation call which

  1. is incorrectly written
  2. the method does not exist

Reformatted:

UIView.animate(
   withDuration: 2,
   delay: 1,
   options: [],
   (using: transitionContext.finalFrame(for: fromView)),
   animations: {
     fromView.view.frame = finalFrameForVC
   },
   completion: { _ in            
     transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
   }
)

Note the (using: transitionContext.finalFrame(for: fromView)),. You cannot wrap a part of the method in parentheses including one of the external parameter names, it would have to be:

UIView.animate(
   withDuration: 2,
   delay: 1,
   options: [],
   using: transitionContext.finalFrame(for: fromView),
   animations: {
     fromView.view.frame = finalFrameForVC
   },
   completion: { _ in            
     transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
   }
)

That is what is causing the error. However, there is also no animation method with using: part, therefore I suppose it's just a copy-paste error and you actually want just:

UIView.animate(
   withDuration: 2,
   delay: 1,
   options: [],
   animations: {
     fromView.view.frame = finalFrameForVC
   },
   completion: { _ in            
     transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
   }
)
Extensity answered 23/7, 2018 at 16:50 Comment(0)
F
1

I had the same problem just now. and i fix it like this:

enter image description here

and like the example above that: self.view must be assigned to another variable, ant the view should be force cast: view!, and then compile will work successfully.

Frisch answered 18/12, 2018 at 4:52 Comment(1)
Hi, Please never post a screenshot of your code, simply use the CODE TAGS to post your code.Chelyabinsk
J
1

Really silly n00b answer,I had the same issue

"Expression type '@lvalue CGRect' is ambiguous without more context"

It was cause because I pressed return before CGFloat. Check to make sure it's on the same line. Hope this helps somebody.

Jackknife answered 21/2, 2019 at 17:44 Comment(0)
L
0

I received this error when I tried to create a CGRect and forgot to add .constant to the end of a variable name for an NSLayoutConstraint

Lithographer answered 3/2, 2019 at 2:35 Comment(0)
V
0

Like Rory Prior wrote above I got this error trying to make a CGPoint and I needed to specify that the parameters were CGFloat but I also needed to label the parameters x: and y: going into CGPoint so that CGPoint knew to expect CGFloat. Here's the code:

let topRight = CGPoint(x:CGFloat(cellTitleLabel.frame.maxX),y:CGFloat(cellTitleLabel.frame.minY))
Vespine answered 13/3, 2019 at 14:47 Comment(0)
P
0

The example

myView.frame = CGRect(x: 0, y: 0, width: CGFloat(videoImaView.frame.width * CGFloat(0.4)), height: height)
Pinkham answered 12/9, 2019 at 12:56 Comment(0)
C
0

Explicitly declare a copy of the variable you want to change then assign it back.

func clickButton() {
    UIView.animateWithDuration(animationDuration, animations: {
        let buttonFrame = self.button.frame
        buttonFrame.origin.y = buttonFrame.origin.y - 1.0
        self.button.frame = buttonFrame
    }
}

credit to Rishi's answer here: https://mcmap.net/q/409023/-how-can-i-move-an-image-in-swift

Carney answered 10/2, 2020 at 20:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.