Подтвердить что ты не робот

Скрыть серый объемный оверлей при использовании MPVolumeView?

Я поставил MPVolumeView над фильмом, который я играю. Проблема в том, что всякий раз, когда я настраиваю vol с помощью MPVolumeView, появляется стандартный серый оверлей (тот, который появляется, когда вы используете переключатель Rocker на iPhone). Есть ли способ отключить стандартное серое наложение?

4b9b3361

Ответ 1

Возможно, я немного опоздал, но я думаю, что у меня есть что-то полезное для добавления. Если вы просто ищете ответ, перейдите к Как я его исправим?

Что такое 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 в своем супервизоре, как показано в следующей трассировке стека:

MPVolumeView stack trace

В чем была моя проблема?
Короче говоря, я сделал что-то вроде этого:

- (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
}

Ответ 2

Обычно, когда отображается 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, даже если вы разместили над ним фильм.

Ответ 3

Это может помочь.

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    self.volumeView.hidden = NO;
    [self.volumeView willMoveToSuperview:self.volumeView.superview];
    [self.volumeView didMoveToSuperview];

}

Ответ 4

Самый простой способ сделать это.....

- (void) viewDidLoad 
{
    [super viewDidLoad];
    MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame: CGRectZero];
    [self.view addSubview: volumeView];
    ...
}

взято refrence из этого потока applicationMusicPlayer извещения о громкости