Casey West
Casey West

Reputation: 576

Expand UITableViewCell UIImage

I have a UITableViewCell with two images, my goal is to expand these images upon a long press by the user. In the best case scenario the image would cover the entire screen with a small 'x' or something to close.

I have the following function I'm using within the custom UITableViewCell, but the image only expands the size of the cell. I can't figure out how to expand the image over the entire tableview/navBar/tabbar of the superview.

@objc func answerOneLongPress(_ sender: UILongPressGestureRecognizer) {
    let imageView = sender.view as! UIImageView
    let newImageView = UIImageView(image: imageView.image)
    let screenSize = UIScreen.main.bounds
    let screenWidth = screenSize.width
    let screenHeight = screenSize.height
    newImageView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
    newImageView.backgroundColor = .black
    newImageView.contentMode = .scaleAspectFit
    self.addSubview(newImageView)
}

Please let me know if you need more information. I feel like this should be happening in the UITableViewController as opposed to the cell, but haven't been able to get it working that way.

Upvotes: 0

Views: 82

Answers (1)

Matic Oblak
Matic Oblak

Reputation: 16774

You should not add your view to cell but to a view controller or to a key window. That depends on your needs. what happens in your case is your image view is added on a cell and is being clipped and also it is not positioned correctly.

I would use some kind of object that handles presenting of this image. Let the code speak for itself:

class ImageOverlayController {

    private var startFrame: CGRect
    private var backgroundView: UIView
    private var imageView: UIImageView

    private init(startFrame: CGRect, backgroundView: UIView, imageView: UIImageView) {
        self.startFrame = startFrame
        self.backgroundView = backgroundView
        self.imageView = imageView
    }

    private convenience init() { self.init(startFrame: .zero, backgroundView: UIView(), imageView: UIImageView())  }

    static func showPopupImage(inController viewController: UIViewController? = nil, fromImageView imageView: UIImageView) -> ImageOverlayController {
        guard let targetView = viewController?.view ?? UIApplication.shared.keyWindow else { return ImageOverlayController() } // This should never happen

        let startFrame = imageView.convert(imageView.bounds, to: targetView)

        let backgroundView: UIView = {
            let view = UIView(frame: targetView.bounds)
            view.backgroundColor = UIColor.black.withAlphaComponent(0.0)
            return view
        }()

        let newImageView: UIImageView = {
            let view = UIImageView(frame: startFrame)
            view.image = imageView.image
            return view
        }()

        let controller = ImageOverlayController(startFrame: startFrame, backgroundView: backgroundView, imageView: imageView)

        backgroundView.addSubview(newImageView)
        targetView.addSubview(backgroundView)

        UIView.animate(withDuration: 0.3) {
            backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
            newImageView.frame = targetView.bounds
        }

        return controller

    }

    func dimiss(completion: (() -> Void)? = nil) {
        UIView.animate(withDuration: 0.3, animations: {
            self.imageView.frame = self.startFrame
            self.backgroundView.backgroundColor = self.backgroundView.backgroundColor?.withAlphaComponent(0.0)
        }) { _ in
            self.backgroundView.removeFromSuperview()
            completion?()
        }
    }

}

As you say a button must still be added which may then call dismiss on the view.

Note: The code I provided was not really tested but just quickly put together. Let me know if there are any issues so I modify it.

Upvotes: 1

Related Questions