【发布时间】:2009-07-22 05:57:48
【问题描述】:
我需要禁用 UIActionSheet 中的按钮。经过一些操作后,我需要再次启用它们。那么有没有办法做到这一点。
谢谢
【问题讨论】:
标签: iphone
我需要禁用 UIActionSheet 中的按钮。经过一些操作后,我需要再次启用它们。那么有没有办法做到这一点。
谢谢
【问题讨论】:
标签: iphone
基于多个线程,我将答案汇总到 UIActionSheet 上的一个类别中,并添加了一个 setButton:toState 方法,如下所示。 希望对您有所帮助:
@interface UIActionSheet(ButtonState)
- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enbaled;
@end
@implementation UIActionSheet(ButtonState)
- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enabled {
for (UIView* view in self.subviews)
{
if ([view isKindOfClass:[UIButton class]])
{
if (buttonIndex == 0) {
if ([view respondsToSelector:@selector(setEnabled:)])
{
UIButton* button = (UIButton*)view;
button.enabled = enabled;
}
}
buttonIndex--;
}
}
}
@end
【讨论】:
Swift 3.0 版本:
let actionSheet = UIAlertController(title:nil, message:nil, preferredStyle:UIAlertControllerStyle.actionSheet)
actionSheet.addAction(UIAlertAction(title:"Modify", style:UIAlertActionStyle.default, handler:{ action in
// Do your thing here
}))
let disabledDelete = UIAlertAction(title:"Cannot delete this item", style:UIAlertActionStyle.destructive, handler:nil)
disabledDelete.isEnabled = false
actionSheet.addAction(disabledDelete)
actionSheet.addAction(UIAlertAction(title:"Cancel", style:UIAlertActionStyle.cancel, handler:nil))
self.present(actionSheet, animated:true, completion:nil)
【讨论】:
稍微改进了 Reuven 的版本 [唉,我不能给他添加评论,因为我还没有“声誉”……]。
@interface UIActionSheet (ButtonEnabled)
- (void)setButtonAtIndex:(NSUInteger)index Enabled:(BOOL)enabled;
@end
@implementation UIActionSheet (ButtonEnabled)
- (void)setButtonAtIndex:(NSUInteger)index Enabled:(BOOL)enabled
{
for (UIView* view in self.subviews) {
if ([view isKindOfClass:[UIButton class]]) {
if (index-- == 0) {
[(UIButton*)view setEnabled:enabled];
break;
}
}
}
}
@end
前面的 respondsToSelector: 检查是多余的,因为我们已经在检查 UIButton(这是一个 UIControl 子类,都支持 setEnabled)。为了与 Apple 的 NSArrays 保持一致,我也更改为“AtIndex”和 NSUInteger,但这主要是化妆品。
整体方法似乎工作正常,但请注意,它确实假设按钮子视图的顺序与构建操作表时按钮索引的顺序精确匹配,这在任何 AFAIK 中都没有严格记录。
【讨论】:
所提供的解决方案不适用于 iOS 8。如果有人没有为此使用 UIAlertController(这是 Apple 推荐的做法),这就是我修改 @Reuven 的答案以使其也适用于 iOS 8 的方式:
(第二阶段基于this所以回答)
- (void)setButton:(NSInteger)buttonIndex toState:(BOOL)enabled {
SEL selector = NSSelectorFromString(@"_alertController");
//iOS 8
if ([self respondsToSelector:selector]) {
UIAlertController *alertController = [self valueForKey:@"_alertController"];
if ([alertController isKindOfClass:[UIAlertController class]]){
UIAlertAction *action = alertController.actions[buttonIndex];
[action setEnabled:enabled];
}
//iOS 7
}else{
for (UIView* view in self.subviews){
if ([view isMemberOfClass:NSClassFromString(@"UIAlertButton")]) {
if (buttonIndex == 0) {
if ([view respondsToSelector:@selector(setEnabled:)]){
UIButton* button = (UIButton*)view;
button.enabled = enabled;
}
}
buttonIndex--;
}
}
}
}
【讨论】:
这可能有点晚了。但是,我想出的方法是创建 UIButton(s) 并添加它们 到 UIActionSheet 子视图。确保将这些按钮放在顶部并完全覆盖要替换的默认 UIActionSheet 按钮。当 UIButton 放置在默认的 UIActionSheet 按钮上时,它的 UIResponder 优先于 UIActionSheet 按钮 UIResponder。因此,这样做您可以禁用和启用这些按钮,但是您希望在 UIViewController 逻辑中的任何位置。这可能是访问 SDK 的私有方法(如上 - UIThreePartButton)的替代方法,并且苹果可能会拒绝您的应用程序。我相信这符合 Apple 准则。
即
// Instantiate once
if (self.actionSheet==nil) {
UIActionSheet *as = [[UIActionSheet alloc]
initWithTitle:@""
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:@"Load Data"
otherButtonTitles:@"Update Data",nil];
//[actionSheet showInView:self.view];
self.loadUIButton.frame = CGRectMake(24.0f,25.0f,275.f,46.0f);
[as addSubview: self.loadUIButton];
self.updateUIButton.frame = CGRectMake(24.0f,78.0f,275.f,46.0f);
[as addSubview: self.updateUIButton];
//[actionSheet addSubview: self.cancelUIButton];
//[as showFromToolbar: self.navigationController.toolbar];
self.actionSheet = as;
[as release];
}
[self.actionSheet showFromToolbar: self.navigationController.toolbar];
【讨论】:
这些按钮是 UIActionSheet 的子视图,它们的类是 UIThreePartButton
你可以得到它们并做你想做的一切:
UIActionSheet *a = [[UIActionSheet alloc]initWithTitle:@"" delegate: nil cancelButtonTitle: @"c" destructiveButtonTitle: @"d" otherButtonTitles: @"ot", nil];
[a showInView: window];
for(UIView *v in [a subviews])
{
if([[v description] hasPrefix: @"<UIThreePartButton"] )
{
v.hidden = YES; //hide
//((UIButton*)v).enabled = NO; // disable
}
}
【讨论】: