我想禁用 UIAction 表中的按钮并在某个条件为真后启用它们。我如何实现这一目标?有任何想法吗?
7 回答
我发现克雷格的答案对我不起作用(在 OS 3.1 上)。经过一番挖掘,我发现的子视图UIActionSheet
实际上是一个无证类 UIThreePartButton
无论如何,这对我有用(作为UIActionSheetDelegete
方法的一部分实现)
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet // before animation and showing view
{
for (UIView* view in [actionSheet subviews])
{
if ([[[view class] description] isEqualToString:@"UIThreePartButton"])
{
if ([view respondsToSelector:@selector(title)])
{
NSString* title = [view performSelector:@selector(title)];
if ([title isEqualToString:@"Button 1"] && [view respondsToSelector:@selector(setEnabled:)])
{
[view performSelector:@selector(setEnabled:) withObject:NO];
}
}
}
}
}
希望对其他人有所帮助,尽管我会回应 Ed Marty 的问题,即您是否最好完全从操作表中省略这些按钮而不是这样做。与往常一样,在使用未记录的功能时,存在应用商店拒绝的风险,尽管如果 Apple 在未来的操作系统版本中再次更改 API,此代码会优雅地失败。
在操作表打开时,是否存在可以更改的情况,这可能导致按钮变为启用状态?如果没有,我认为更好的方法是根据您的情况更改工作表显示的按钮。
否则,处理此问题的唯一方法是遍历工作表的子视图,就像克雷格所说的那样,并寻找UIButton
对象。不过,我会小心使用按钮的标题,因为标题可以(并且应该!)针对不同的语言进行本地化。因此,与标题的比较并不是那么可靠。由于您没有创建按钮,因此您也不真正知道每个按钮的tag
oraction
是什么,所以这也有点困难。
subviews
据推测,按钮将按照您指定的顺序出现在数组UIActionSheet
中Cocoa Touch SDK 的。因此,我主要担心会因为使用未记录的功能而被 App Store 拒绝。
UIActionSheet 不适用于自定义。它应该显示实际的可用选项集。它不应该在顶部更改按钮的可用性。只需删除未使用的按钮,或改用自定义视图
这可能有点晚了。但是,我想出的方法是创建 UIButton(s) 并将它们添加到 UIActionSheet 子视图。确保将这些按钮放在顶部并完全覆盖要替换的默认 UIActionSheet 按钮。当 UIButton 放置在默认的 UIActionSheet 按钮上时,它的 UIResponder 优先于 UIActionSheet 按钮 UIResponder。因此,这样做您可以禁用和启用这些按钮,但是您希望在 UIViewController 逻辑中的任何位置。这可能是访问 SDK 的私有方法(如上 - UIThreePartButton)的替代方法,并且苹果可能会拒绝您的应用程序。我相信这遵循了 Apple 的指导方针。
即设置 UIButtons 以便在某些条件发生后启用/禁用。
// Instantiate once within a method
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];
注意:这在我之前构建的应用程序中运行良好。
您可以在 UIActionSheetDelegate 中尝试 [actionSheet valueForKey:@"_buttons"],如下所示:
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{
for (UIButton *btn in [actionSheet valueForKey:@"_buttons"])
{
[btn setBackgroundImage:[UIImage imageNamed:@"btnActionSheetUp.png"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"btnActionSheetDown.png"] forState:UIControlStateHighlighted];
}
}
希望这在 sdk 的未来版本中不会改变。
如果您将视图添加到操作表,该视图将不会收到任何事件。您需要查看操作表的超级视图。
请参阅下面我如何添加带有修饰事件的按钮:
- (void)didPresentActionSheet:(UIActionSheet *)actionSheet{
CGRect rect = CGRectMake(0,0, 320, 480);
UIButton* anImage = [[UIButton alloc] init];
[anImage setTitle:@"GHello worl" forState:UIControlStateNormal];
[anImage setTitle:@"GHello worl dfasd" forState:UIControlStateHighlighted];
[anImage setTitle:@"GHello worl selected" forState:UIControlStateSelected];
//[anImage setBackgroundImage:[UIImage imageNamed:@"photo.png"] forState:UIControlStateNormal];
[anImage addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
rect = CGRectMake(0,0, 320, 220);
anImage.frame =rect;
[actionSheet.superview addSubview:anImage];
[anImage release];
}
当我有一个根据某些条件更改的操作表时,我遇到了类似的问题。我完全省略了操作表中不适用的选项,但在某些情况下,我最终会得到一个只有一个选项的操作表。这似乎有点傻,因为我可以立即激活该选择而根本不显示工作表。
但是,我还希望用户了解单击屏幕上的某个按钮会给他们一个可供选择的选项列表。这就是为什么我想在只有一个选择的情况下也显示操作表。我想过禁用不适用的选项,而不是从工作表中省略它们,但这也感觉不对。
我的案例与在自定义底栏中有一个用户图标有关,然后按下它会出现以下选择:
- 如果登录
- 我的简历
- 登出
- 如果没有登录
- 登录