13

我在我正在播放的电影上放置了一个 MPVolumeView。问题是,每当我使用 MPVolumeView 调整音量时,就会出现标准的灰色音量叠加(当您使用 iPhone 上的摇杆开关时会出现)。有没有办法禁用标准的灰色覆盖?

4

4 回答 4

18

我可能有点晚了,但我想我有一些有用的东西要补充。如果您只是在寻找答案,请跳至我是如何解决的?

是什么MPVolumeView
该类MPVolumeView用于在屏幕上放置一个控制系统音量的滑块。它应该防止系统音量覆盖在屏幕上出现,但有时不会。当我将自己的 MPVolumeView 添加到视图层次结构时遇到了这个问题,但是当我拖动滑块时仍然看到覆盖出现。

如何MPVolumeView判断它何时可见?
这是我问自己的问题。不知何故,该类检测它是否可见,并告诉系统相应地隐藏或显示系统卷覆盖。这是因为 Apple 并不真正希望您使用该类只是为了防止覆盖出现,而不是实际向用户显示滑块 UI(如 myell0w 的回答)。

以下是我认为MPVolumeView尝试检查它是否真的可见的方法:

  1. 当视图被添加到超级视图时,由viewWillMoveToSuperview:and检测到viewDidMoveToSuperview,它会启动一个短计时器。
  2. superview当计时器触发时,视图通过递归检查属性来遍历其视图祖先树。
  3. MPVolumewView检查其每个祖先是否具有hidden = NO并且alpha大于某个小值(可能为 0.05)。

可能还有其他我不知道的检查,因为此代码当然是封闭源代码。步骤 1 中的计时器在那里,因此如下代码不会“欺骗”视图:

MPVolumeView *volView = [[MPVolumeView alloc] init];
[self.view addSubview:volView];
volView.hidden = YES;

因为它hidden不会立即检查该属性,而是在它已经设置为YES.

我是如何弄清楚这一切的?一个关键发现是 的实例MPVolumeView正在调用isHidden其父视图,如以下堆栈跟踪所示:

MPVolumeView 堆栈跟踪

我的问题是什么?
简而言之,我做了这样的事情:

- (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's 实例化期间,它的超级视图被隐藏了。

我是如何解决的?
一旦我意识到MPVolumeView班级如何判断它是否可见,我就有一个简单的方法来“愚弄”它。我在负责的类中添加了以下方法MPVolumeView

- (void)refreshVolumeView {
    [self.volView willMoveToSuperview:self];
    [self.volView didMoveToSuperview];
}

并在每次我需要强制视图重新评估它是否可见时调用它。此方法只是假装将视图重新添加到层次结构中。一旦我满足了视图评估的条件(每个祖先都不是隐藏的或非常低的 alpha),我就调用它,并且覆盖层停止显示。在上面的示例代码中,我将添加一行:

- (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
}
于 2014-10-25T22:46:33.410 回答
7

通常当 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,即使您在电影上方放置了音量视图。

于 2012-06-08T18:37:11.937 回答
1

这可能会有所帮助。

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

}
于 2016-09-01T12:20:57.333 回答
0

最简单的方法来做到这一点......

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

从此线程应用程序音乐播放器音量通知中获取参考

于 2014-12-17T13:25:13.077 回答