Я поставил MPVolumeView поверх фильма, который я играю. Проблема в том, что всякий раз, когда я настраиваю громкость с помощью MPVolumeView, появляется стандартное серое наложение громкости (тот, который появляется при использовании переключателя на iPhone). Есть ли способ отключить стандартное серое наложение?
Скрыть наложение серого тома при использовании MPVolumeView?
Ответы (4)
Я могу немного опоздать, но я думаю, что могу добавить что-то полезное. Если вы просто ищете ответ, перейдите к разделу Как я это исправил?
Что такое MPVolumeView
?MPVolumeView
используется для размещения на экране ползунка, который управляет громкостью системы. Предполагается, что это предотвращает появление наложения системного тома, когда оно отображается на экране, но иногда этого не происходит. Я столкнулся с этой проблемой, когда добавил свой собственный MPVolumeView в иерархию представлений, но все еще видел, что наложение появляется при перетаскивании ползунка.
Как MPVolumeView
определяет, что он виден?
Это вопрос, который я задал себе. Каким-то образом класс определяет, виден он или нет, и указывает системе скрывать или отображать наложение системного тома соответствующим образом. Это связано с тем, что Apple на самом деле не хочет, чтобы вы использовали класс только для предотвращения появления наложения, фактически не отображая пользовательский интерфейс слайдера для пользователя (как в ответе myell0w).
Вот как, я думаю, MPVolumeView
пытается проверить, действительно ли он виден:
- Когда представление добавляется в суперпредставление, что определяется
viewWillMoveToSuperview:
иviewDidMoveToSuperview
, оно запускает короткий таймер. - Когда таймер срабатывает, представление пересекает дерево предков представления, рекурсивно исследуя свойство
superview
. MPVolumewView
проверяет, что у каждого из его предковhidden = NO
иalpha
больше некоторого небольшого значения (вероятно, 0,05).
Могут быть и другие проверки, о которых я не знаю, так как этот код, конечно, с закрытым исходным кодом. Таймер на шаге 1 существует, чтобы код, подобный следующему, не «обманул» представление:
MPVolumeView *volView = [[MPVolumeView alloc] init];
[self.view addSubview:volView];
volView.hidden = YES;
потому что он будет проверять свойство hidden
не сразу, а через некоторое время, после того как оно уже будет установлено в YES
.
Как я во всем этом разобрался? Ключевой находкой было то, что экземпляр MPVolumeView
вызывал isHidden
в своем суперпредставлении, как показано в следующей трассировке стека:
В чем была моя проблема?
Короче говоря, я сделал что-то вроде этого:
- (void)viewDidLoad {
// Add an MPVolumeView to my view
self.volView = [[MPVolumeView alloc] init];
[self.view addSubview:self.volView];
self.volView.hidden = YES;
}
- (void)someButtonTouched {
// Show the MPVolumeView (and hopefully hide the system overlay)
self.volView.hidden = NO;
}
Но когда я перетаскивал ползунок только что появившегося MPVolumeView
, оверлей все равно появлялся. Я понял, что это произошло потому, что во время создания экземпляра MPVolumeView
его супервизор был скрыт.
Как я это исправил?
Как только я понял, как класс MPVolumeView
оценивает видимость объекта, у меня появился простой способ «обмануть» его. Я добавил следующий метод в класс, отвечающий за MPVolumeView
:
- (void)refreshVolumeView {
[self.volView willMoveToSuperview:self];
[self.volView didMoveToSuperview];
}
и вызывал его каждый раз, когда мне нужно заставить представление переоценивать, было ли оно видимым. Этот метод просто делает вид, что повторно добавляет представление в иерархию. Как только я удовлетворяю условиям, которые оценивает представление (каждый предок не скрыт или имеет очень низкую альфу), я вызываю его, и наложение перестает отображаться. В приведенном выше примере кода я бы добавил одну строку:
- (void)viewDidLoad {
// Add an MPVolumeView to my view
self.volView = [[MPVolumeView alloc] init];
[self.view addSubview:self.volView];
self.volView.hidden = YES;
}
- (void)someButtonTouched {
// Show the MPVolumeView (and hopefully hide the system overlay)
self.volView.hidden = NO;
[self refreshVolumeView]; // <<< This line was added
}
Обычно, когда виден MPVolumeView, HUD не появляется. Я использую следующий метод в своем приложении, и он работает нормально:
+ (void)preventSystemVolumePopup {
// Prevent Audio-Change Popus
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-2000., -2000., 0.f, 0.f)];
NSArray *windows = [UIApplication sharedApplication].windows;
volumeView.alpha = 0.1f;
volumeView.userInteractionEnabled = NO;
if (windows.count > 0) {
[[windows objectAtIndex:0] addSubview:volumeView];
}
}
По сути, он просто добавляет вид объема в первое окно в месте, где его никто не может видеть, и, таким образом, предотвращает отображение HUD системного объема. Интересно, почему вы видите этот HUD, хотя вы ставите объемный вид над своим фильмом.
Это может помочь.
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.volumeView.hidden = NO;
[self.volumeView willMoveToSuperview:self.volumeView.superview];
[self.volumeView didMoveToSuperview];
}
Самый простой способ сделать это.....
- (void) viewDidLoad
{
[super viewDidLoad];
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame: CGRectZero];
[self.view addSubview: volumeView];
...
}
взято из этой темы уведомление о громкости applicationMusicPlayer