【发布时间】:2010-11-07 21:27:33
【问题描述】:
我有一个带有各种图像按钮的工具栏,是在 Interface Builder 中创建的。
我希望能够以编程方式在按下时将其中一个按钮替换为活动指示器,然后放回原始按钮,但在活动完成时将其颜色从白色更改为黄色。
这是否可以通过 IB 构建的工具栏实现,还是我必须考虑以编程方式构建整个工具栏和自定义视图?
【问题讨论】:
标签: iphone interface-builder uitoolbar
我有一个带有各种图像按钮的工具栏,是在 Interface Builder 中创建的。
我希望能够以编程方式在按下时将其中一个按钮替换为活动指示器,然后放回原始按钮,但在活动完成时将其颜色从白色更改为黄色。
这是否可以通过 IB 构建的工具栏实现,还是我必须考虑以编程方式构建整个工具栏和自定义视图?
【问题讨论】:
标签: iphone interface-builder uitoolbar
我认为应该可以。您可以尝试在 ViewController 类中为该特定按钮创建一个 IBOutlet ,并将按钮从 IB 连接到该插座,或者您可以使用该 UIToolbar 实例的 items 属性(您确实对此有参考,不是吗? ?) 并在其中找到适当的项目,创建一个包含修改后项目的新 NSArray,并将其设置回那个 toolbar.items 属性。
HTH
【讨论】:
这是我使用的方法 完全以编程方式管理工具栏似乎要简单得多......
在您的视图控制器中,将一组或多组 UIBarButtonItem 项声明为属性项,并将工具栏声明并连接为 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.
【讨论】:
这是我在类似情况下所做的一个示例。我想使用 Interface Builder 构建工具栏,但根据是否“检查”来切换 BarButtonItems 之一。在此示例中,需要注意一些关键事项。头文件中为类定义了以下2个成员变量:
NSMutableArray *toolbarItems;
IBOutlet UIToolbar *toolbar;
NSUInteger checkUncheckIndex;
当我想更新检查状态时,我调用这个函数...请注意定义了一个名为 checkUncheckClicked 的选择器,当单击 UIToolbar 中的特定按钮时会调用它。并且 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 中为类释放。
希望这会有所帮助!
【讨论】:
请注意 - 工具栏会去除图标中的任何颜色,因此您仍然无法将其设为黄色。您需要更改图像形状以指示“开启”。
或者,您需要使用 UIButtons 加载 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];
}
【讨论】:
自从发布这些答案后,情况发生了很大变化。这是一个 Swift 2.0 解决方案。
您要替换的原始UIBarButtonItem 是如何以编程方式创建的并不重要。您只需要UIToolbar 插座。例如,要替换左起第二个项目,请执行以下操作:
var toolbarItems = self.toolbar.items
let newItem = UIBarButtonItem(barButtonSystemItem: .Play, target: self, action: "play")
toolbarItems![1] = newItem
self.toolbar.setItems(toolbarItems, animated: true)
【讨论】:
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
}
}
}
【讨论】:
对于您在 IB 中创建的整个工具栏(也就是说,不是单个工具栏项),创建一个 IBOutlet:
@IBOutlet weak var toolbarThatYouMade: UIToolbar!
这是一组单独的工具栏项,因此您可以使用[0] 索引访问最左边的成员(例如):
toolbarThatYouMade.items![0].image = UIImage(named: "New Image")
此代码假定您的资产中有一个名为“新图像”的图像。
然后您可以触发工具栏项的图像更改,而无需访问该特定项本身;例如,如果您将它用于媒体播放器之类的东西,您可以从以下位置切换暂停/播放图像:
a) 暂停/播放按钮本身,
b) 停止按钮,
c) 当您收到播放器状态更改的通知时,
或
d) 完全不同的东西。 (勇敢点!大胆点!以“b”开头的其他东西!)
【讨论】: