Coming soon - Get a detailed view of why an account is flagged as spam!
view details
35
Anybody have any experience with context menus and AVPlayerLayer? When you dismiss/cancel there's an odd flash of the background color.
Post Body

I'm having a small but annoying issue with the new iOS 13 context menus where if you present a view controller that has an AVPlayerLayer playing, when you present, instead of animating away nicely it flashes to white (or whatever your background color is). This is pretty jarring if the AVPlayerLayer is playing, say, a dark video and the background goes white.

Relatively straightforward sample code (latest Xcode, latest iOS 13.1 beta), you can just copy paste the following into New Project > Single View App:

```swift import UIKit import AVFoundation

class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad()

    let myView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
    myView.backgroundColor = .black
    myView.isUserInteractionEnabled = true
    view.addSubview(myView)

    let interaction = UIContextMenuInteraction(delegate: self)
    myView.addInteraction(interaction)
}

}

extension ViewController: UIContextMenuInteractionDelegate { func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { return UIContextMenuConfiguration(identifier: nil, previewProvider: { () -> UIViewController? in return ViewController2() }, actionProvider: nil) } }

class ViewController2: UIViewController { override func viewDidLoad() { super.viewDidLoad()

    let assetURL = URL(string: "https://giant.gfycat.com/DependentFreshKissingbug.mp4")!
    let hardcodedSize = CGSize(width: 480, height: 600)
    let player = AVPlayer(url: assetURL)
    player.play()

    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = CGRect(x: 0.0, y: 0.0, width: hardcodedSize.width, height: hardcodedSize.height)
    playerLayer.videoGravity = .resize
    view.layer.addSublayer(playerLayer)

    preferredContentSize = hardcodedSize
}

} ```

It's very minor, but it's also not the greatest visual effect (as said, kinda jarring). With the outgoing 3D Touch Peek/Pop, the AVPlayerLayer would fade out nicely instead of jumping to the background color. I'm assuming internally it takes a snapshot, doesn't like the fact that it's not a static view, and ignores the content. Or something.

Note: oddly it seems to behave properly in Simulators. Try on device to see. Okay I just realize this is probably a bug then.

Ideas:

  • In viewWillDisappear or the cancel delegate for the animation, use CoreImage and a filter to figure out the average color, then set that as the backgroundColor of the outgoing view controller.
  • Use AVAssetImageGenerator to take a snapshot of the AVPlayerLayer video when cancelling, add that as a subview, and it'll fade out the image view instead

Neither of these work as once those methods are called, the overlay has seemingly decided what it will look like and will take no further modifications (subviews added/background color changes don't show up).

So I'm considering like progressively taking snapshots of the video as a subview, replacing the image frequently, so that way when it animates it'll have a somewhat up to date frame of the video, which looks a lot better than a white flash.

Ideas?

Author
Account Strength
100%
Account Age
14 years
Verified Email
Yes
Verified Flair
No
Total Karma
1,715,057
Link Karma
529,042
Comment Karma
607,499
Profile updated: 3 days ago
Posts updated: 5 months ago
Objective-C / Swift

Subreddit

Post Details

We try to extract some basic information from the post title. This is not always successful or accurate, please use your best judgement and compare these values to the post title and body for confirmation.
Posted
5 years ago