Interface Builder で作成された、さまざまな画像ボタンを備えたツールバーがあります。
押されたときにプログラムでボタンの 1 つをアクティビティ インジケーターに置き換え、元のボタンを元に戻し、アクティビティが完了すると色を白から黄色に変更できるようにしたいと考えています。
これは IB で構築されたツールバーで可能ですか、それともプログラムでツールバー全体とカスタム ビューを構築する必要がありますか?
Interface Builder で作成された、さまざまな画像ボタンを備えたツールバーがあります。
押されたときにプログラムでボタンの 1 つをアクティビティ インジケーターに置き換え、元のボタンを元に戻し、アクティビティが完了すると色を白から黄色に変更できるようにしたいと考えています。
これは IB で構築されたツールバーで可能ですか、それともプログラムでツールバー全体とカスタム ビューを構築する必要がありますか?
これは、私が同様の状況で行ったことの例です。Interface Builder を使用してツールバーを作成したかったのですが、「チェック」されているかどうかに基づいて BarButtonItems の 1 つを切り替えました。この例では、注目すべき重要な点がいくつかあります。次の 2 つのメンバー変数は、ヘッダー ファイル内のクラスに対して定義されています。
NSMutableArray *toolbarItems;
IBOutlet UIToolbar *toolbar;
NSUInteger checkUncheckIndex;
チェック済みのステータスを更新したいときは、この関数を呼び出します... UIToolbar の特定のボタンがクリックされたときに呼び出される checkUncheckClicked という名前のセレクターが定義されていることに注意してください。また、UIToolbar はツールバーへの IBOutlet として設定されます。別の方法として、UIBarButtonItem をアウトレット自体として接続し、それをロジックとして使用してボタンのインデックスを識別することもできます。さらに言えば、時間が経っても変化しない場合は、ボタンのインデックスをハードコーディングすることもできます。最後に、checked.png と unchecked.png が交互にプロジェクトに含まれています。
- (void)updateBarButtonItemChecked:(BOOL)checked {
if (toolbarItems == nil) {
toolbarItems = [[NSMutableArray arrayWithArray:toolbar.items] retain];
checkUncheckIndex = -1;
for (NSUInteger i = 0; i < [toolbarItems count]; i++) {
UIBarButtonItem *barButtonItem = [toolbarItems objectAtIndex:i];
if (barButtonItem.action == @selector(checkUncheckClicked)) {
favoriteIndex = i;
break;
}
}
}
if (checkUncheckIndex != -1) {
UIBarButtonItem *barButtonItem = [[[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:checked ? @"checked.png" : @"unchecked.png"]
style:UIBarButtonItemStylePlain target:self action:@selector(checkUncheckClicked)] autorelease];
[toolbarItems replaceObjectAtIndex:checkUncheckIndex withObject:barButtonItem];
toolbar.items = toolbarItems;
}
}
もちろん、toolbarItems と toolbar は、クラスの dealloc で解放する必要があります。
お役に立てれば!
Swift にはもっと簡単な方法があります。私の場合、タッチごとに再生ボタンと一時停止ボタンを切り替えています。
@IBAction func playandPause(sender: UIBarButtonItem) { // Here we are creating an outlet. Hook this up to the bar button item.
for (index, button) in toolbarItems!.enumerate() { // Enumerating through all the buttons
if button === sender { // === operator is used to check if the two objects are the exact same instance in memory.
var barButtonItem: UIBarButtonItem!
if mediaplayer.playing {
mediaplayer.pause()
barButtonItem = UIBarButtonItem.init(barButtonSystemItem: .Play, target: self, action: #selector(playandPause(_:)))
}else {
mediaplayer.play()
barButtonItem = UIBarButtonItem.init(barButtonSystemItem: .Pause, target: self, action: #selector(playandPause(_:)))
}
toolbarItems![index] = barButtonItem // Replace the old item with the new item.
break // Break once we have found the button as it is unnecessary to complete the rest of the loop
}
}
}
これらの回答が投稿されてから、多くの変更がありました。これがSwift 2.0ソリューションです。
UIBarButtonItem
置き換えるオリジナルがどのようにプログラムで作成されたかは重要ではありません。必要なのはUIToolbar
コンセントだけです。たとえば、左から 2 番目の項目を置き換えるには、次のようにします。
var toolbarItems = self.toolbar.items
let newItem = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "play")
toolbarItems![1] = newItem
self.toolbar.setItems(toolbarItems, animated: true)
これが私が使用したアプローチです。ツールバーを完全にプログラムで管理する方がはるかに簡単に思えたので....
ビュー コントローラーで、UIBarButtonItem アイテムの 1 つ以上のセットをプロパティ アイテムとして宣言し、ツールバーを UIToolbar プロパティとして宣言してフックアップします。また、項目を保持するために 1 つ以上の配列を宣言します。
実装では、viewDidLoad を割り当てて、たとえば UIBarButtonItems を設定します。
playButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemPlay
target:self
action:@selector(handlePlayClick)];
柔軟なボタン(配置など)は次のように宣言されます
flexButton1 =[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil action:nil];
ツールバーがサポートするさまざまなタイプのボタンを処理する initMethods がいくつかあります。すべて上記と同様の構文に従います。注目すべきは、ターゲットとアクションの設定です。Target: 通常は self です。action は、ボタンがトリガーする機能の名前です。
UIBarButtons を割り当てた後、initWithObjects を使用してそれらを配列に追加します。
次に、ボタンをツールバーに割り当てるには、呼び出します
[toolbar setItems:<array name>];
コードの最後で UIBarButtons と配列の割り当てを解除することを忘れないでください。
お役に立てれば。さらにコードが必要な場合はお知らせください。
リッチ D.
私はそれが可能であるべきだと思います。ViewController クラスで特定のボタン用の IBOutlet を作成してみて、IB からそのアウトレットにボタンを接続するか、その UIToolbar インスタンスの items プロパティを使用することができます (それへの参照がありますよね? ?) そしてそこから適切なアイテムを見つけ、変更されたアイテムで新しい NSArray を作成し、それをその toolbar.items プロパティに戻します。
HTH
これに関する注意-ツールバーはアイコンの色をすべて取り除くので、それでも黄色にすることはできません。代わりに「オン」を示すように画像の形状を変更する必要があります。
または、UIButtonを使用してBarButtonItemsをロードし(initWithCustomViewを使用)、ボタンの画像を適切に設定する必要があります。
HTH
試す:
- (void)setTitle:(NSString *)title forItem:(int)item ofToolbar:(UIToolbar *)tb {
NSMutableArray *newItems = [tb.items mutableCopy];
UIBarButtonItem *old = [newItems objectAtIndex:1],
*titled = [[UIBarButtonItem alloc] initWithTitle:title style:old.style target:old.target action:old.action];
[newItems replaceObjectAtIndex:1 withObject:titled];
tb.items = newItems;
[titled release];
}
IB で作成したツールバー全体 (つまり、個々のツールバー項目ではない) に対して、IBOutlet を作成します。
@IBOutlet weak var toolbarThatYouMade: UIToolbar!
[0]
これは個々のツールバー項目の配列であるため、インデックスを使用して (たとえば) 一番左のメンバーにアクセスします。
toolbarThatYouMade.items![0].image = UIImage(named: "New Image")
このコードは、アセットに「New Image」という名前の画像があることを前提としています。
その後、特定のアイテム自体にアクセスしなくても、ツールバー アイテムの画像変更をトリガーできます。たとえば、これをメディア プレーヤーのようなものに使用している場合、画像の一時停止/再生を次のように切り替えることができます:
a) [一時停止/再生] ボタン自体、
b) [停止] ボタン、
c) プレーヤーの変更が通知されたとき状態、
または
d)まったく別のもの。(勇気を出して! 大胆に! 'b' で始まる何かになろう!)