0

I am trying to show a view modally. The view is shown as a "Cross Dissolve" "over full screen". I am passing the screen shot to the controller. I am then trying to crop the screenshot and retain only the part that would be under the view. This i am blurring and adding to the view.

The code works as far as blurring goes, but i have two problems. 1) The image is at double scale, which will be something to do with retina display, but i am never sure how to fix that. 2) the other is that, having tried everything I can think of, i cannot get the coordinate of the "canvas" in a coordinate system that helps me correctly crop the view.

I'd really appreciate help with this thanks karl

    override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let window = appDelegate.window!
    let splitViewController = window.rootViewController as! UISplitViewController;

    let cropFrame = UIView().convertRect(self.canvas.frame, toView: splitViewController.view)

    let croppedScreenShotCG = CGImageCreateWithImageInRect(screenShot?.CGImage, cropFrame)
    let croppedScreenShot = UIImage(CGImage:croppedScreenShotCG)

    var blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Light)
    var blurEffectView = UIVisualEffectView(effect: blurEffect)

    blurEffectView.frame = CGRectMake(0, 0, self.canvas.frame.width, self.canvas.frame.height)

    let blurImageView = UIImageView(image:croppedScreenShot)
    blurImageView.addSubview(blurEffectView)

    let blurColorCast = UIView(frame: CGRectMake(0, 0, self.canvas.frame.width, self.canvas.frame.height))
    blurColorCast.backgroundColor = UIColor.cloverColor10pc()
    blurColorCast.alpha = 0.2
    blurImageView.addSubview(blurColorCast)

    self.canvas.addSubview(blurImageView)
    self.canvas.sendSubviewToBack(blurImageView)

    UIImageWriteToSavedPhotosAlbum(croppedScreenShot, nil, nil, nil)
}

I am getting the screen shot like this:

            let layer = window.layer
        let scale = UIScreen.mainScreen().scale
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

        layer.renderInContext(UIGraphicsGetCurrentContext())
        let screenshot = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

1 Answers1

0

Instead of using UIImage's CGImage: you can use imageWithCGImage:scale:orientation: which takes a scale parameter to account for retina screens.

See: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/#//apple_ref/occ/clm/UIImage/imageWithCGImage:scale:orientation:

But personally I prefer to avoid doing anything in code, if there's a reasonable way to do it with storyboards.

Here's an example project that has a blur effect for the back of a modal presentation that doesn't use any code at all.

The only thing worth noting is that for the view controller that's being presented, the root view background color is set to clear (otherwise the view controller that's presenting it would be obscured).

MathewS
  • 2,267
  • 2
  • 20
  • 31
  • Thank you so much, I too would prefer to do this without code. Thanks for taking the time to reply. –  Sep 13 '15 at 11:50
  • Ok, this worked to start with. But something has changed. Now whenever I try to show view that is set to 'clear' it shows clear while transitioning into place, but once in place goes black. This happens everywhere i set a view to clear. Any ideas? thanks, karl –  Sep 13 '15 at 15:21
  • Hmm... In your segue attributes panel, is the presentation type set to 'Over Full Screen' (or 'Over Current Context')? – MathewS Sep 13 '15 at 16:02
  • The segue is "Full Screen" and "Cover Vertical" –  Sep 13 '15 at 16:30
  • Change "Full Screen" to "Over Full Screen" and it should be good! Depending on the effect you're going for you might also want to change "Cover Vertical" to "Cross Dissolve". – MathewS Sep 13 '15 at 17:30
  • The segue itself doesn't give that option, the navigation controller and view controller being displayed (modally) do. They are both set to "Over Full Screen" but still no clear view –  Sep 13 '15 at 17:47
  • Do i need to do anything with "Defines Context" and "Provides Context"? –  Sep 13 '15 at 17:48
  • When you click on the segue in the storyboard and view the attributes inspector in the utilities pane there should be options to enter the segue identifier, segue class etc. The 'Segue' option should be 'Present Modally' (UIPresentationController is intended for modal presentations) and 'Presentation' should be 'Over Full Screen'. Double check that, but if that's not it I'm not sure I can help without a sample project. – MathewS Sep 13 '15 at 18:04
  • Ok, I finally got there, the options you mention were not available on the segue. However, they are on the navigation and view controllers. so i set the segue to "default" and "default" and the the navigation and view controllers as you suggest. It now seems to work. Thank you for all your, help. –  Sep 13 '15 at 18:36
  • Interestingly, doing this stops the unwind segue working! It fires, but doesn't dismiss the view. -- Just changed to another rewind point and seemed to work, strange –  Sep 13 '15 at 18:55
  • If you have a sample project if be happy to take a look later today. I thought that those options have been available for a while, but maybe they were added with Xcode 7 (assume that you're using Xcode 6.x) – MathewS Sep 13 '15 at 19:07
  • Thanks, but I am happy to struggle with it for a bit now. The clear background is now working, and I have a workaround for the segue. Thanks for all your help, karl –  Sep 13 '15 at 19:12