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

Настроить внешний вид кнопки

Я использую стандартное наложение градиента (сделано в Photoshop), чтобы кнопки выглядели лучше в моем приложении. Я добавил кнопку Airplay, но эстетика не подходит.

enter image description here

Я действительно хочу наложить на него слой градиента, чтобы он соответствовал, но все, что я могу найти, показывает только, как это сделать с помощью png, а не с существующим UIView. Если не градиентный слой, мне просто нужно каким-то образом изменить внешний вид кнопки Apple в эфире, сохранив при этом ее функциональность.

Код настройки прост:

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:frame];
[volumeView setShowsVolumeSlider:NO];
[bottomPanel addSubview:volumeView];

Как я могу получить внешний вид этого элемента для соответствия моим элементам управления?

4b9b3361

Ответ 2

После принятия ответа @Erik B и награждения его щедростью, я обнаружил, что для его работы требуется больше настроек. Я размещаю здесь в интересах будущих поисковиков SO.

Проблема, которую я наблюдал, заключалась в том, что внутренние механизмы кнопок будут назначать изображение, основанное на текущем состоянии воспроизведения. Таким образом, любые настройки, которые я делал во время init, не будут придерживаться, если приемник Airplay исчезнет, ​​или состояние каким-то образом изменилось. Чтобы решить эту проблему, я настраиваю наблюдение KVO на кнопке alpha. Я заметил, что кнопка всегда исчезает в/из, которая является анимацией на alpha.

MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectZero];
[volumeView setShowsVolumeSlider:NO];
for (UIButton *button in volumeView.subviews) {
    if ([button isKindOfClass:[UIButton class]]) {
        self.airplayButton = button; // @property retain
        [self.airplayButton setImage:[UIImage imageNamed:@"airplay.png"] forState:UIControlStateNormal];
        [self.airplayButton setBounds:CGRectMake(0, 0, kDefaultIconSize, kDefaultIconSize)];
        [self.airplayButton addObserver:self forKeyPath:@"alpha" options:NSKeyValueObservingOptionNew context:nil];
    }
}
[volumeView sizeToFit];

Затем я наблюдаю измененное значение кнопок alpha.

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([object isKindOfClass:[UIButton class]] && [[change valueForKey:NSKeyValueChangeNewKey] intValue] == 1) {
        [(UIButton *)object setImage:[UIImage imageNamed:@"airplay.png"] forState:UIControlStateNormal];
        [(UIButton *)object setBounds:CGRectMake(0, 0, kDefaultIconSize, kDefaultIconSize)];
    }
}

Не забудьте удалить наблюдателя, если вы уничтожите кнопку

- (void)dealloc {
    [self.airplayButton removeObserver:self forKeyPath:@"alpha"];
    …
}

На основе наблюдения кода кнопка будет разбита, если Apple изменит иерархию внутреннего представления MPVolumeView, чтобы добавить/удалить/изменить виды, чтобы появилась другая кнопка. Это делает его хрупким, поэтому используйте на свой страх и риск, или придумайте план b, если это произойдет. Я использую его более года в производстве без каких-либо проблем. Если вы хотите увидеть его в действии, проверьте основной экран игрока в Ambiance

Ответ 3

Наконец-то я нашел Bluetooth-гарнитуру, чтобы проверить тестовую кнопку. Изменение его внешнего вида было очень простым. Здесь код:

for (UIButton *button in volumeView.subviews) {
    if ([button isKindOfClass:[UIButton class]]) {
        [button setImage:[UIImage imageNamed:@"custom-route-button.png"] forState:UIControlStateNormal];
        [button sizeToFit];
    }
}

Что там все.

Ответ 4

Приведенный выше код не работает для меня (поскольку кнопка AirPlay добавляется позже). В качестве обходного пути вы можете использовать стандартный UIButton в своем пользовательском интерфейсе и запускать AirPlay в (скрытой) кнопке MPVolumeView с помощью

for (UIButton *button in volumeView.subviews)
{
    if ([button isKindOfClass:[UIButton class]]) 
    {
        [button sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
}

Побочным эффектом является то, что кнопка не скроется автоматически, когда доступен только один маршрут, что может или не может быть желательным.

Ответ 5

Я создал собственный метод, который отлично работает...

-(void)airplayIcon:(CGRect)rect {
    UIView *aiplayView = [[UIView alloc] initWithFrame:self.bounds];
    aiplayView.clipsToBounds = true;
    aiplayView.backgroundColor = [UIColor clearColor];
    [self addSubview:aiplayView];

    MPVolumeView *airplayVolume = [[MPVolumeView alloc] initWithFrame:aiplayView.bounds];
    airplayVolume.showsVolumeSlider = false;
    [aiplayView addSubview:airplayVolume];

    for (UIButton *button in airplayVolume.subviews) {
        [button setFrame:self.bounds];
        if ([button isKindOfClass:[UIButton class]]) {
            [button setImage:[UIImage imageNamed:@"normal.png"] forState:UIControlStateNormal];
            [button setImage:[UIImage imageNamed:@"selected.png"] forState:UIControlStateSelected];
            [button sizeToFit];

        }

    }

}