Reputation: 334
Since iOS 13, showsRouteButton from MPVolumeView has been deprecated
let vv = MPVolumeView()
vv.showsRouteButton = false
Warning is :
'showsRouteButton' was deprecated in iOS 13.0: Use AVRoutePickerView instead.
Apple is telling me to use AVRoutePickerView for routing, which makes no sense as in my case I do not want to use any routing stuff, I only want to hide it. It seems there's no more not deprecated way to do this.
If it's deprecated it should be hidden by default else apple should allow us to hide it...
Am I right to say it's an apple API error ?
Upvotes: 10
Views: 2122
Reputation: 63
This works for me, not sure if it robust:
import MediaPlayer
extension MPVolumeView {
/// Compiler warning 'showsRouteButton' was deprecated in iOS 13.0: Use AVRoutePickerView instead.
/// But the route button will show by default if we don't set it false.
/// We can set by key value to silent the warning. But also need prevent Apple remove the key in the future.
func hideRouterButtonIfNecessary() {
let bugKey = "showsRouteButton"
var count: UInt32 = 0
guard let properties = class_copyPropertyList(MPVolumeView.self, &count) else { return }
for i in 0..<Int(count) {
let property = properties[i]
let name = property_getName(property)
let str = String(cString: name)
if str == bugKey {
self.setValue(false, forKey: bugKey)
break
}
}
free(properties)
}
}
Upvotes: 0
Reputation: 4659
In iOS 15.0 the route button of MPVolumeView
shows the route button as a subview. The safest way to get rid of it without a deprecation warning is to look for the button and hide it:
volume.subviews.first(where: { $0 is UIButton })?.isHidden = true
Unlike just ignoring the warning or setting the value with key-value coding (as suggested by @spasbil), this will not crash the app in a future iOS release where Apple may have removed the deprecated showsRouteButton
. However, it has the disadvantage of leaving an empty space right of the slider.
Setting the value through key-value coding does lead to a visually more satisfying solution, where the slider extends over the full width of the MPVolumeView
. Using a #keypath
expression as suggested by @spasbil shows the same warning in Xcode 13.0. Using a String
literal rather than a #keypath
expression, as suggested in a comment, avoids this warning. It does not resolve the danger of crashing on future iOS releases where showsRouteButton
will have disappeared.
Apple never tells us when they will remove a deprecated property, but they rarely do it in a minor release. So we can hope that showsRouteButton
will stay around at least for iOS 15.* releases. A forward compatible way to get rid of the route button is therefore:
if #available(iOS 16, *) {
volumeView.subviews.first(where: { $0 is UIButton })?.isHidden = true
} else {
volumeView.setValue(false, forKey: "showsRouteButton")
}
We might need to get back to this during the next major release beta season, presumably next summer. In the meantime, use this at your own risk. In the unlikely case that Apple removes the property in a later release of iOS 15.*, your app will crash. In the more likely case that showsRouteButton
stays available but deprecated in iOS 16, your MPVolumeView
will leave some unwanted space until you bump up the availability check.
Upvotes: 1
Reputation: 279
For now just to remove the warning and the default route button I used this immediately after initializing the MPVolumeView
.
if volumeView.value(forKey: #keyPath(MPVolumeView.showsRouteButton)) as? Bool == true { volumeView.setValue(false, forKey: #keyPath(MPVolumeView.showsRouteButton)) }
I check via key value paths if the value of showsRouteButton
is true
and sets it to false
if it is.
Upvotes: 2