我遇到了一些奇怪的iOS8行为,我不知道如何处理它。对我来说似乎是一个错误。也许你对解决方法有个好主意。
重现方法:创建一个至少有两个选项的UIActionSheet。在iOS8中,您可以一次选择多个选项。只需触摸em:在设备和模拟器上工作。这可能也会在糟糕的瞄准时发生。
委托方法
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;
将被调用两次。如果它会停在这里这很容易:只需忽略第二个委托调用。问题是_UIAlertControllerShimPresenterWindow永远不会被解雇,这会导致UI阻塞,因为我们的UIApplication的窗口没有收到任何触摸事件。如果你运行
po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
在调试模式下,您将获得以下输出:
<_UIAlertControllerShimPresenterWindow: 0x7bf5a3d0; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; gestureRecognizers = <NSArray: 0x7bf5af80>; layer = <UIWindowLayer: 0x7bf5a620>>
| <UIView: 0x7bf5c460; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7bf5c3f0>>
也是委托方法
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
永远不会打电话给。
将UIApplication的UIWindow重新设置为脏兮兮的黑客,如:
[[(MyApplicationDelegate *) [UIApplication sharedApplication].delegate window] makeKeyAndVisible];
不起作用。您对如何解决这个问题有任何其他想法吗?
要重现,只需将以下ViewController放入UINavigationController,就会出现问题......万一你不相信我:
#import "ViewController.h"
@interface ViewController () <UIActionSheetDelegate>
@end
@implementation ViewController
- (void)loadView
{
self.view = [[UIView alloc] initWithFrame: CGRectZero];
self.view.backgroundColor = [UIColor whiteColor];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithTitle:@"ActionSheet" style:UIBarButtonItemStylePlain target:self action:@selector(buttonTouchUpInside:)];
self.toolbarItems = @[buttonItem];
[self.navigationController setToolbarHidden: NO];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark Target Action
- (IBAction)buttonTouchUpInside:(id)sender
{
UIActionSheet *aSheet = [[UIActionSheet alloc] initWithTitle:@"Choose an option" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:@"Option 1", @"Option 2", @"Option 3", @"Option 4", nil];
[aSheet showFromToolbar: self.navigationController.toolbar];
// [aSheet showInView: self.view]; // doesn't make any difference
}
#pragma mark UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(@"Clicked at button index %lu", (unsigned long) buttonIndex);
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(@"Did dismiss with button index %lu", (unsigned long) buttonIndex);
}
- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSLog(@"Will dismiss with button index %lu", (unsigned long) buttonIndex);
}
@end
答案 0 :(得分:1)
我认为解决此问题的最佳方法是在iOS 8中使用UIAlertController
而不是UIActionSheet
。
以下是如何以适用于iOS 8或iOS 7的方式实现它的示例:
- (IBAction)buttonCallingActionSheetPressed:(UIBarButtonItem *)sender
{
id alertControllerClass = NSClassFromString(@"UIAlertController");
if (alertControllerClass)
{
UIAlertAction *sheetAction = nil;
UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
sheetAction = [UIAlertAction actionWithTitle:@"Do something"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[self actionSheetSelectedIndex:0];
}];
[actionSheetController addAction:sheetAction];
sheetAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[self actionSheetSelectedIndex:1];
}];
[actionSheetController addAction:sheetAction];
[self presentViewController:actionSheetController animated:YES completion:nil];
}
else
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:@"Do something", nil];
[actionSheet showFromToolbar:self.navigationController.toolbar];
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self actionSheetSelectedIndex:buttonIndex];
}
- (void)actionSheetSelectedIndex:(NSInteger)selectedAction
{
// Your logic goes here
}
答案 1 :(得分:0)
您所描述的场景不可能发生,具有Apple发布的此级别。委托分配或类似的东西可能存在一些问题。但是,您可以使用此方法来解除委托方法中的ActionSheet(这只是一种解决方法):
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated;
像这样:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
[actionSheet dismissWithClickedButtonIndex:actionSheet.cancelButtonIndex animated:YES];
}
答案 2 :(得分:0)
此问题已在iOS 8.3 +。
中修复