我使用标准渐变叠加(在photoshop中完成)使按钮在我的应用中看起来更漂亮。我添加了一个Airplay按钮,但美学并不匹配。
我真的想在它上面放一个渐变层使它匹配,但我能找到的任何东西只显示如何使用png,而不是现有的UIView。如果不是渐变层,我只需要任何方式来改变Apple airplay按钮的外观,同时保持其功能完好无损。
设置代码很简单:
MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:frame];
[volumeView setShowsVolumeSlider:NO];
[bottomPanel addSubview:volumeView];
如何使其外观与我的控件匹配?
答案 0 :(得分:16)
在接受了@Erik B的回答并向他颁发奖金之后,我发现需要进行更多调整才能让它发挥作用。我在这里发帖是为了未来搜索者的利益。
我看到的问题是按钮的内部机制会根据当前的播放状态分配图像。因此,如果Airplay接收器消失,或者状态以某种方式改变,我在init期间进行的任何自定义都不会坚持。为了解决这个问题,我在按钮的alpha
键上设置了KVO观察。我注意到按钮总是淡入/淡出,这是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
答案 1 :(得分:15)
我终于找到了一个蓝牙耳机,以便我可以测试按钮。改变它的外观非常简单。这是代码:
for (UIButton *button in volumeView.subviews) {
if ([button isKindOfClass:[UIButton class]]) {
[button setImage:[UIImage imageNamed:@"custom-route-button.png"] forState:UIControlStateNormal];
[button sizeToFit];
}
}
这就是它的全部内容。
答案 2 :(得分:7)
我认为自iOS 6以来有更好的解决方案: 使用
- (void)setRouteButtonImage:(UIImage *)image forState:(UIControlState)state;
在MPVolumeView上。
答案 3 :(得分:3)
以上代码对我不起作用(因为后来添加了AirPlay按钮)。作为一种解决方法,您可以在UI中使用标准UIButton并使用
在(隐藏)MPVolumeView
按钮中触发AirPlay
for (UIButton *button in volumeView.subviews)
{
if ([button isKindOfClass:[UIButton class]])
{
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
副作用是当只有一条路线可用时,按钮不会自动隐藏,这可能是也可能不是所希望的行为。
答案 4 :(得分:1)
我创建了一个完美运行的自定义方法......
-(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];
}
}
}