The long version: I am writing an app for iOS 8 in Swift, and its main functionality requires it to display a slideshow of sorts of pictures and videos. Considering that, to my knowledge, an AVPlayer cannot display pictures (I've tried feeding it an image URL in the same way I've fed it a video URL, and no luck), this requires me to add and remove a UIImageView or an AVPlayer from the view in order to display the appropriate content. However, in order to show the content correctly, I have to hide the app's navigationbar by default. The idea is to show it again if the user taps on the view. The view has a TapGestureRecognizer that serves this purpose. These tap gestures work correctly, assuming the view's content is the imageview. However, if the view presently contains the AVPlayer, the gestures are not received, rendering me unable to allow the user to show the navigationbar and leave the view. Here is how the AVPlayer is added to the view:
if (Utilities.IsVideo(url)) {
var escapedUrl = url.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let player = AVPlayer(URL: NSURL(string: escapedUrl!))
var cont = AVPlayerViewController()
cont.player = player
self.addChildViewController(cont)
self.view.addSubview(cont.view)
cont.view.frame = self.view.frame
player.play()
}
The short version: I have a view in an iOS app that contains a TapGestureRecognizer. The taps do not pass through an AVPlayer that is added to the view. How do I detect these taps?
It is worthy of mention that if the user taps on one of the media controls (such as the play button), the tap gesture is then recognized and its action triggered.
Related
i just develop a music player streaming app recently probably using avplayer. The situation is, i have a table view with list of songs which auto play feature, where, First, user need to choose song from table view, whenever the current song end, the table view will autoscroll and highlight to the next cell. Here how i did it inside AVPlayerItemDidPlayToEndTime delegate function:
let indexPosition = IndexPath(row: MusicPlayerManager.shared.latestIndex, section: 0)
self.tableView.scrollToRow(at: indexPosition, at: .none, animated: true)
self.tableView.selectRow(at: indexPosition, animated: true, scrollPosition: .none)
where MusicPlayerManager.shared.latestIndex is the current cell index. And everything work well accordingly.
For your information, i have declare AVPlayer as global variable (singleton) to allow the music playing in any page (viewcontroller) as below:
final class MusicPlayerManager {
static let shared = MusicPlayerManager()
private init() { }
var player: AVPlayer!
var latestIndex = 0
var playlistFrame = Playlist()
}
All still work well, where, i can pause, stop, play , auto play and others.
The situation and the problem occur when the songs is currently playing then i navigate to other ViewControllers, and go back to my MusicViewController (main vc), then, the auto scroll and highlight (select row) didnt work anymore. The player is still goes as usual without problems. The problem only on table view MusicViewController is my main viewcontroller where all the tableview and the music player are there. If i stay on the MusicViewController page without navigate to other controller, everything goes well.
To make the autoscroll work, i need to start over the flow, where i need to choose the list of music from the table view.
i navigate to other page using segue, where each time i going back to MusicViewController page, viewdidload() being called
i load all list music into tableview inside viewdidload(). Already try inside viewdidappear, but still not work
sorry for my bad english. Because english is not my native language. Thanks
i need to know atleast the cause of this behaviour. I try manually execute function scrollToRow and selectRow using button, it works well. It just not work automatically on code.
I have a WKWebview that I basically want to override the zooming behavior for. I want to scale up the font, so what I have right now is a UIView on top of the WKWebview that I've added a UIPinchGestureRecognizer to that does some evalutateJavascript call on the webview. However, now the Webview doesn't receive tapping or scrolling events as I believe the overlay view is capturing them. Is there a way to send it down to the webview? These are all in a single VC with outlets to both the webview and the overlay view. I wanted to override the behvaior directly for the WKWebview but I can't seem to get it to work.
Basically I know if you need to deliver gesture event to other responders, just set the pinchGestureRecognizer.cancelsTouchesInView = false
I'm implementing an app that retrieves a video stream using WebRTC (libjingle_peerconnection library). At some moment, the stream (RTCVideoTrack) could be removed. When this happens in the UIView (RTCEAGLVideoView) still show the last frame of the stream. I want to set that View to black. How can I do it?
For now I'm removing the stream with the following code, but as I said, last frame keeps showing on the view.
remoteVideoTrack.setEnabled(false) // RTCVideoTrack object
remoteVideoTrack.remove(videoView) // videoView is the RTCEAGLVideoView UI object
remotePeerConnection.close()
I encountered a similar issue. However, in may case a black view wasn't acceptable and I needed the renderer view to become completely transparent.
Since the video chat view controller in my case is displayed in a container, I was able to make the renderer last frame disappear by completely reloading the container.
This is the relevant code:
// Kill renderer
vcWebRtc?.willMove(toParent: nil)
vcWebRtc?.view.removeFromSuperview()
vcWebRtc?.removeFromParent()
vcWebRtc = UIStoryboard.instance(from: .WebRTC).instantiateInitialViewController() as? WebRtcVC
if vcWebRtc != nil{
addChild(vcWebRtc!)
viewWebRtcContainer.addSubview(vcWebRtc!.view)
vcWebRtc!.view.frame = viewWebRtcContainer.bounds
vcWebRtc?.didMove(toParent: self)
vcWebRtc?.delegate = self}
I am loading my AVPlayerController on a specified UIView. Is there a way to hide only the fullscreen button shown on the AVPlayerController?
What you can do is hide all the controls using:
YourAVPlayerViewControllerName.showsPlaybackControls = false
and then create your own custom controls for the player
EDIT:
Also as mentioned in the comments, you cannot remove only one button, if you need the excat the same then you need to customise your view based on your requirment
I'm afraid you cant, but you can create a customized player using AVPlayerLayer then you can do almost anything you want in it but you need to handle everything manually, slider and playback Controls and so.
there are already lots of tutorials on how to achieve that like this one
I want to add my own custom dropdown when a video is playing and the user swipes down. However, the default dropdown with asset info and audio settings always shows first when I swipe. I know I can get rid of it by making the video not be fullscreen, but then I would lose playback controls.
Any help would be greatly appreciated, thanks!
Update
let swipeDownGR = UISwipeGestureRecognizer(target: self, action: #selector(self.handleSwipes(sender:)))
swipeDownGR.direction = .down
view.addGestureRecognizer(swipeDownGR)
The default dropdown usually captures the gesture before my recognizer does.
I'm not too sure if you can get rid of some of the default behaviors that AVPlayerController provides. I actually would recommend creating your own custom playback controls (which isn't actually as hard as it sounds). All you have to do is to create a translucent UIView and overlay it on top of the AVPlayer, and add the elements that you want which gives you full control over the controls/elements that are there when the video is paused.
let vc: AVPlayerViewController = ... //your view controller
vc.playbackControlsIncludeInfoViews = false