Johan Enstam
Johan Enstam

Reputation: 125

Error "Optional type" when converting to Swift 3 syntax

When converting my project to the Swift 3 syntax I ran into several errors and was able to solve all but one.

The error message I'm getting is:

"Initializer for conditional binding must have Optional type, not 'UIView'"

Here is the code(I'm using Yalatis cocoapod ColorMatchTabs):

  public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    self.transitionContext = transitionContext

    guard let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to),
    let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
        let containerView = transitionContext.containerView else {
        return
    }
    containerView.addSubview(toViewController.view)

    let needShow = mode == .show
    if !needShow {
        containerView.addSubview(fromViewController.view)
    }

    let animatedViewController = needShow ? toViewController : fromViewController
    let initialRect = CGRect(origin: startPoint, size: CGSize.zero)
    let initialCircleMaskPath = UIBezierPath(ovalIn: initialRect)
    let extremePoint = CGPoint(x: startPoint.x, y: animatedViewController.view.bounds.height)
    let radius = hypot(extremePoint.x, extremePoint.y)
    let finalCircleMaskPath = UIBezierPath(ovalIn: initialRect.insetBy(dx: -radius, dy: -radius))

    let maskLayer = CAShapeLayer()
    maskLayer.path = needShow ? finalCircleMaskPath.cgPath : initialCircleMaskPath.cgPath
    animatedViewController.view.layer.mask = maskLayer

    let maskLayerAnimation = CABasicAnimation(keyPath: "path")
    maskLayerAnimation.fromValue = initialCircleMaskPath.cgPath
    maskLayerAnimation.fromValue = needShow ? initialCircleMaskPath.cgPath : finalCircleMaskPath.cgPath
    maskLayerAnimation.toValue = needShow ? finalCircleMaskPath.cgPath : initialCircleMaskPath.cgPath

    maskLayerAnimation.duration = transitionDuration(using: transitionContext)
    maskLayer.add(maskLayerAnimation, forKey: "path")
}

This is were it fails:

guard let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to),
    let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
        let containerView = transitionContext.containerView else {
        return
    }

And the error message appears here:

let containerView = transitionContext.containerView else {
        return
    }

I'm not very good at swift yet, obviously not good enough to solve this error. I'm grateful for all the help I can get!

Upvotes: 0

Views: 512

Answers (1)

Swifty
Swifty

Reputation: 3760

transitionContext.containerView is not an optional, you don't need to put it inside a guard-let statement because it will always have a value

Replace this:

guard let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to),
let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
    let containerView = transitionContext.containerView else {
    return
}

with

guard let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to),
let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) else {
    return
}
let containerView = transitionContext.containerView

Upvotes: 1

Related Questions