Remove/hide Full screen button from MPMoviePlayerController Standard Controls - ios

I want to remove/hide the full screen button from MPMoviePlayerController standard controls as full screen mode is creating lot of problems and also not a requirement of my app.I just want the play,stop,forward,reverse controls. Can anybody help me?

There's no standard way to do this. Here are your options.
You could set the MPMoviePlayerController's controlStyle to None and create your own custom controls. Cons: this is a lot of work.
You could use the NSNotificationCenter to intercept the MPMoviePlayerWillEnterFullscreenNotification and immediately set fullScreen mode to NO. Cons: based on the iOS version of the user, this may cause a flicker or some glitchy effect.
You could go through the MPMoviePlayerController view's subviews until you get to a MPInlineTransportControls view which contains the controls, the slider and the play/pause button and the full screen button which are all of class MPTransportButton. Find that one and you can hide it or remove it from its superview. Cons: as of right now this passes app store reviews and works perfectly on all currently supported iOS versions. But this could change at any time. If Apple decides to redo their default video player you may end up with non working code.

Related

Firebase Screen name issue with modal views in iOS 13 and above

In our app we are tracking screen views manually by adding relevant codes in viewWillAppear functions. With iOS 13, with the non fullscreen modals, the viewWillAppear of the parent screen won't get called when the modal is dismissed and hence wrong screen names are reported there after, for events originating from the parent screen.
I have checked the Detecting sheet was dismissed on iOS 13 , but the solution to implement  UIAdaptivePresentationControllerDelegate helps when you manually swipes down.
I then turned off manual tracking and turned on Automatic tracking and surprisingly the screen classes are determined right. Question is how Firebase is figuring that out?
Of-course I can't use auto tracking as we need custom screen names.
I believe this could be a generic issue for whoever using manual screen name tracking and have non full screen modals. Just wanted to check what's the best way to solve this.
Couple of ideas I had was
Make all modals full screen. Not nice for our app
Implement extra delegates in those modals to let the parent know its dismissed. Not sure its a nice way
Setting screen names on each event? Could that be even possible?
If there are any other nicer/ cleaner option let me know.

Dumb Question: How do I make AVPlayer look like everyone else's?

My Current Setup (Subject to Change)
I have a simple iOS app right now that plays an M3U8 using AVPlayer. In order to place custom UI elements on top of the player (text alerts, mostly) I jimmy-rigged what is probably a terrible architecture, and I'm open to the idea of scrapping the whole thing and starting over.
First I created a new UIView which I called "MyPlayer". This UIView has a XIB file with nothing in it
Next I created a new NSObject (now UIView) which I called "PlayerDisplay". This class also has a XIB file associated with it, which contains an ImageView and a Label
In MyPlayer.m's init method, I instantiate a PlayerDisplay using an initWithMyPlayer method
In PlayerDisplay.m's initWithMyPlayer method, I created an AVPlayerViewController instance
I called [myPlayer addSubview:controller.view] and controller.view.frame = myPlayer.bounds to get the player to display within my view
I called [[NSBundle bundleForClass:[self class]] loadNibNamed:#"PlayerDisplay" owner:self options:nil] to load the XIB with the ImageView and Label
I called [myPlayer addSubview:self.contentView] and self.contentView.frame = myPlayer.bounds to get the player to display my ImageView and Label over top of the player
It felt hack-y at the time, and it feels hack-y now. But it allows me to insert a single MyPlayer view into an app and have it load all of my custom control and display logic. And it works (at least as far back as iOS 8, which is the oldest I've tested, and as far forward as iOS 12.4, which is the newest I've tested)
However I recently wanted to look into creating custom controls and looked to some industry leaders for inspiration (Netflix, YouTube, etc) - and I noticed that every other video player on the market looks the same, but none of them look like mine.
Netflix
ESPN
Hulu
Amazon Prime
YouTube
Twitch
Every one of these players has:
White icons with transparent backgrounds placed directly on top of the video (no control bar background)
A play/pause button in the dead center of the video
Seek back/forward buttons on either side of the play button
A seek bar at the bottom of the video
A single icon in the top-left
A horizontal list of icons in the top-right
Not only that, but Netflix and ESPN use the exact same icon set seek icons (although upon further inspection, the play buttons and cast buttons differ slightly)
Similarly, Hulu and Amazon Prime use the exact same icon set It was pointed out that Hulu and Amazon Prime differ sufficiently to be different icon sets. I still stand by Netflix and ESPN having identical seek buttons, though. I've rearranged the pictures to make this more obvious
It's too unbelievable to me that every single company disabled the default controls, built their own user interface from scratch, and they all just so happened to look identical. I feel like either AVPlayer has an option to enable this layout, Apple provides a framework for building UIs from icon sets which lays things out in this manner, or there may be a third-party library that is considered the "de facto" standard for video streaming, much like ExoPlayer is the leading name on Android
Compare and contrast all of the above players with my player, which is using Apple's default UI for an AVPlayerViewController:
The control bar has a background color and rounded corners
The play button is within the control bar
There are no seek forward / back buttons
There's only a volume control in the top right instead of a list of icons
How do I make my player look like theirs?
Is there just a flag in AVPlayer to say "use the other UI"? Is there a third-party library I should be using? What am I doing differently from all of the big names?
Note: I did discover AVPlayerViewControlsStyle, which I should theoretically be able to utilize with avPlayerView.controlsStyle = ..., however as you can tell from my setup above - I don't actually have an instance of AVPlayerView. Just my own custom view and the AVPlayerViewController. I tried typing controller.view.controlsStyle into Xcode to see if it would auto-complete, but it did not - making me think I don't have an AVPlayerView at all
Second Note: I also saw AVPlayerLayer when looking through the official Apple docs. What is that used for? Should I be utilizing it?

How do I support VoiceOver in UIPickerView on an iPad running an iPhone only app (non-universal)?

Generally I look at Apple's UICatalog sample code for basic VoiceOver support however it looks like there is VoiceOver support for UIPickerViews in the sample code. Do I need to provide an accessibilityLabel method somewhere to add VoiceOver support? I tried to implement UIPickerViewAccessibilityDelegate methods but voice over only reads the labels in my picker view and not the hint to swipe up or down to change the values.
Also my picker view is set to the input view of a UITextField. So I'm not sure if that is relevant or not.
Update:
https://github.com/stevemoser/VoiceOverPicker
I created a sample project demonstrating the issue. In the example there is a normal picker view shown and a textfield. There is also a picker that is set to the textfield's input view property. I can't seem to activate the either picker just by tapping on it while using VoiceOver. Though I can activate either one by swiping (left and right) through the views on screen. Any ideas?
Update 2:
Looks like if the app is an iPhone app running on an iPhone or an iPad app running on an iPad it works fine but if it is an iPhone only app running on an iPad, tapping to select a UIPickerView doesn't work.
Are you just doing a vanilla UIPickerView using titles for each row (and not custom views)? If so, there isn't anything that you should have to do.
You mentioned that VoiceOver was correctly reading the label on each row, so we know that the UIPickerView correctly has isAccessibilityElement set to YES. It's also correctly reading the accessibilityLabels.
Is it possible that you're interacting with the picker before it has a chance to read the accessibilityHint? (For the benefit of others, the accessibilityHint is the "swipe or down with one finger to adjust the value" that Steve mentioned in his question.) Or perhaps some notification is changing the VoiceOver focus before the hint has a chance to be read?
By default, if your picker view is accessible, when you focus on it with VoiceOver it will read the something along these lines:
"[ROW LABEL] Adjustable [#number] out of [#total] picker item" a 2 to
3 second pause then "Swipe up or down to select value"
A few of things to note:
There is a 2 to 3 second delay between reading the label and the hint, make sure you wait for it.
If you're providing your own hint, the default one will not get read I believe
Hints are only read when you reach a certain control by either directly pressing it or by swiping right or left to the control. it will not get read if you do a 2 finger swipe down or up.
Make sure you're testing on an actual device and not a simulator as it does not show all of the things VoiceOver announces.

Adding custom button to MPMoviePlayerController (fullscreen)

I have a MPMoviePlayerController instance in my iOS app, that plays a local file in fullscreen mode. This all works fine, but now I want to add a custom button to the window for changing the playback speed. We support both iPhone and iPad in all orientations.
I know how to set the playback speed from code (using setCurrentPlaybackRate), but I need to let the user do it while watching the video, which means adding some kind of button to the playback screen next to the existing buttons, e.g. next to "play", "pause", or in the top bar.
By looking on StackOverflow I have found various replies for questions similar but not quite the same, some saying it cannot be done in fullscreen, some saying it can be done (but is very complex) by creating some kind of overlay, effectively replacing the entire overlay with a custom one.
Although, I have yet to find any code examples (apart from a few snippets without context), getting-started style tutorial or similar for this, so any pointers to example code would be greatly appreciated.
maybe this Apple example could help you
https://developer.apple.com/library/ios/samplecode/MoviePlayer_iPhone/Introduction/Intro.html

UIImagePickerController has two 'camera' buttons when started as front-facing

Since iOS6, whenever I show present a UIImagePickerController from inside a UIPopoverController, I am getting two "take picture" buttons:
This only happens when starting out in front-facing mode. If I start with the rear-camera and then switch after the popover appears, it's okay. Likewise, starting in front-facing and switching to rear will keep the second button there.
Even worse, the 'in picture' button doesn't work. It just tries to focus the camera at that point.
Anyone else seeing this or know of a solution? It doesn't happen when presented full screen, and I saw in Apple's docs that the popover is no longer the recommended way to present the image picker, but that it's also not necessarily bad, either. Unfortunately due to some external requirements, I need to keep it in a popover, and can't do full-screen.
Thanks!
I have exactly the same issue on iOS6. Odd behavior is that it appears only the first time I open the image picker. When closed and opened again, "in-picture" button disappears. Looks like a bug in UIImagePickerController.
To overcome this issue, you can hide image controls by setting showsCameraControls property to NO and use custom overlay view with own controls. Disadvantage of this is that you have to provide all controls then and code action handlers for them.
Unfortunately I didn't find a better way so far.

Resources