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 theAVPlayerLayer
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?
Subreddit
Post Details
- Posted
- 5 years ago
- Reddit URL
- View post on reddit.com
- External URL
- reddit.com/r/iOSProgramm...