0

Hi guys i have just updated XCode to version 11.4 from the app store and when i try to snapshot a UIView on iOS 13.4 like this:

extension UIView {

    func snapshot(at scale: CGFloat) -> UIImage? {

        let renderer = UIGraphicsImageRenderer(size: bounds.size)
        let image = renderer.image { [weak self] context in
            self?.drawHierarchy(in: self?.bounds ?? .zero, afterScreenUpdates: true)
        }

        return image
    }
}

or like that:

extension UIView {

    func snapshotOld(at scale: CGFloat) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, scale)
        guard let currentContext = UIGraphicsGetCurrentContext() else { return nil }
        layer.render(in: currentContext)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

and set the resulting image to UIImageView like that:

class ViewController: UIViewController {

    @IBOutlet private weak var imageView: UIImageView!


    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let image = view.snapshot
        imageView.image = image
    }
}

extension UIView {

    @objc var snapshot: UIImage? {
        snapshot(at: 3.0)
//        snapshotOld(at: 3.0)
    }
}

i get:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIReplicantView _isSymbolImage]: unrecognized selector sent to instance 0x115907c00'
*** First throw call stack:
(0x1ad52c164 0x1ad240c1c 0x1ad42a7e0 0x1b16a5b6c 0x1ad53085c 0x1ad532b60 0x1b1af6cdc 0x1b1af714c 0x1b1af0b30 0x1025061a8 0x102506270 0x1b1010880 0x1b10112cc 0x1b0f25658 0x1b167fc10 0x1b166f13c 0x1b16a088c 0x1ad4a6c54 0x1ad4a18e4 0x1ad4a1d84 0x1ad4a1660 0x1b78b2604 0x1b167615c 0x102507f78 0x1ad31d1ec)
libc++abi.dylib: terminating with uncaught exception of type NSException

I get this both in simulator and on a real device.

Do you guys have any idea why is this happening? I suspect it is a XCode 11.4 bug because this code worked nicely on the older versions

Here is a sample project if you would like to try it out on your machine

Stoyan
  • 1,265
  • 11
  • 20

1 Answers1

2

You're not calling the method you think you are. You have two choices:

  • Change snapshot to snapshott everywhere (or some other nonambiguous alternative).

  • Or else, remove the @objc designation.

Do either of those things, and all will be well.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Yes, this is based on running your code. I'll submit this back to you as a fork. – matt Mar 26 '20 at 16:54
  • it works i was changing the method names not the computed variable name. Thanks a lot :) But what did i call then ? Really weird – Stoyan Mar 26 '20 at 16:57
  • Submitted this as a pull request, check your github repo. – matt Mar 26 '20 at 17:02
  • Yeah, well, this is like what happens when you call a view property `firstResponder` and expose it to Objective-C. Your whole app breaks. :) Cocoa has taken a lot of names and there is no namespacing, so it's your job to pick names that don't overlap Cocoa's names. Which is hard to do, because you don't know what they are. – matt Mar 26 '20 at 17:05
  • 1
    i won't merge your fork, so that people that look at this in the future will see what the issue was and how you fixed it. Here is a link to matt's pull request https://github.com/stoqn4opm/UIReplicantViewCrashExample/pull/1/files – Stoyan Mar 27 '20 at 08:59
  • Open pull request are bad. Please pull, test, and merge, so I can close my fork. Git holds the commit so people can still see it. – matt Mar 27 '20 at 11:14