18

標準のグラデーションオーバーレイ(フォトショップで実行)を使用して、アプリでボタンの見栄えを良くしています。Airplayボタンを追加しましたが、美観が一致していません。

ここに画像の説明を入力してください

グラデーションレイヤーをその上に配置して一致させたいのですが、見つけたものはすべてpngでこれを行う方法を示しているだけで、既存のUIViewは示していません。グラデーションレイヤーでない場合は、何らかの方法で、Appleのエアプレイボタンの機能を損なわずに外観を変更する必要があります。

セットアップコードは簡単です:

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

コントロールに一致するようにこれの外観を取得するにはどうすればよいですか?

4

5 に答える 5

16

@Erik Bの回答を受け入れ、彼に賞金を授与した後、それを機能させるためにさらに調整が必要であることがわかりました。私は将来のSOサーチャーのためにここに投稿しています。

私が見た問題は、ボタンの内部メカニズムが現在のエアプレイ状態に基づいて画像を割り当てることでした。したがって、初期化中に行ったカスタマイズは、Airplayレシーバーがなくなった場合、または状態が何らかの形で変更された場合に固執しませんでした。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を考えてください。私はそれを1年以上本番環境で問題なく使用しています。実際の動作を確認したい場合は、Ambianceのメインプレーヤー画面を確認してください

于 2011-10-28T12:20:12.237 に答える
15

ボタンをテストできるように、ついにBluetoothヘッドセットを見つけました。外観の変更は非常に簡単でした。コードは次のとおりです。

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

これですべてです。

于 2011-03-25T17:09:07.410 に答える
7

更新:iOS 13以降、このメソッドは非推奨になりました。

iOS 6以降、これにはもっと良い解決策があると思います。

- (void)setRouteButtonImage:(UIImage *)image forState:(UIControlState)state;

MPVolumeViewで。

https://developer.apple.com/Library/ios/documentation/MediaPlayer/Reference/MPVolumeView_Class/index.html#//apple_ref/occ/instm/MPVolumeView/setRouteButtonImage:forStateを参照して ください。

于 2014-10-10T08:54:25.993 に答える
3

上記のコードは私には機能しませんでした(AirPlayボタンが後で追加されるため)。回避策として、UIの標準UIButtonを使用して、(非表示の)MPVolumeViewボタンでAirPlayをトリガーできます。

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

副作用は、使用可能なルートが1つしかない場合にボタンが自動的に非表示にならないことです。これは、望ましい動作である場合とそうでない場合があります。

于 2011-10-18T20:00:23.807 に答える
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];

        }

    }

}
于 2015-04-27T22:51:29.913 に答える