在我的项目中,我使用runloop阻塞主线程来实现获取UIAlertController的用户点击结果。以下是测试视图控制器.h和视图控制器.m的代码:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
#import "ViewController.h"
@interface ViewController ()
@end
static NSInteger kButtonIndex = -1;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
BOOL result = [self test];
NSLog(@"Result: %d",result);
}
- (BOOL)test{
kButtonIndex = -1;
NSLog(@"000");
UIAlertController *alerVC = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];
[alerVC addAction:[UIAlertAction actionWithTitle:@"Ok" style:(UIAlertActionStyleDestructive) handler:^(UIAlertAction * _Nonnull action) {
kButtonIndex = 1;
}]];
[alerVC addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
kButtonIndex = 0;
}]];
NSLog(@"111");
[self presentViewController:alerVC animated:YES completion:^{}];
NSLog(@"222");
while (kButtonIndex == -1) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
}
if (kButtonIndex == 1) {
return YES;
}
if (kButtonIndex == 0) {
return NO;
}
return NO;
}
@end在具有任何iOS版本的device iPhone 11或更早的设备上,一旦您轻触屏幕,UIAlertViewController将显示,如果您单击Ok按钮,控制台日志应如下所示:
2021-09-24 16:51:04.146063+0800 TestAlert[1520:46901] 000
2021-09-24 16:51:04.148558+0800 TestAlert[1520:46901] 111
2021-09-24 16:51:04.165442+0800 TestAlert[1520:46901] 222
2021-09-24 16:51:05.774194+0800 TestAlert[1520:46901] Result: 1但是,如果在装有iOS 15的device iPhone 12或更高版本设备上,一旦轻触屏幕,UIAlertViewController将不会显示,控制台日志应如下所示:
2021-09-24 16:51:04.146063+0800 TestAlert[1520:46901] 000
2021-09-24 16:51:04.148558+0800 TestAlert[1520:46901] 111
2021-09-24 16:51:04.165442+0800 TestAlert[1520:46901] 222下面的代码似乎不再起作用了:
while (kButtonIndex == -1) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
}有没有人遇到过这个问题?谢谢!
额外:我们的项目使用Cordova和UIWebView,这个应用程序中的一些远程h5页面来自其他公司(如果我们将webview更改为WKWebView,这些公司需要更新他们的js文件,如cordova.js,这是一项艰巨的工作,所以我们留在UIWebView)……在UIWebView中,一些用户说js confirm()函数在iOS15上不再显示模式视图,我试了很多,发现UIWebView中的js confirm()函数呈现了一个UIAlertController。我试着像这样重写UIWebView确认实现,它在除iPhone 12 iOS15之外的任何设备上都工作得很好:
#import <UIKit/UIKit.h>
@interface UIWebView (Alert)
@end
#import "UIWebView+Alert.h"
@implementation UIWebView (Alert)
static NSInteger kButtonIndex = -1;
- (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame{
kButtonIndex = -1;
UIAlertController *alerVC = [UIAlertController alertControllerWithTitle:@"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
[alerVC addAction:[UIAlertAction actionWithTitle:@"Ok" style:(UIAlertActionStyleDestructive) handler:^(UIAlertAction * _Nonnull action) {
kButtonIndex = 1;
}]];
[alerVC addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
kButtonIndex = 0;
}]];
[[self topViewController] presentViewController:alerVC animated:YES completion:^{}];
while (kButtonIndex == -1) {
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
}
if (kButtonIndex == 1) {
return YES;
}
if (kButtonIndex == 0) {
return NO;
}
return NO;
}
@end实际上,上面的代码与我问题中的最前面的代码几乎是一样的,如果有人可以提供帮助,你可以运行最前面的测试代码来重现问题。
发布于 2021-09-24 14:16:00
我们在iPhone 12上的iOS 15上的动画中遇到了同样的问题。我们使用[NSRunLoop mainRunLoop runUntilDate]来允许动画在继续执行主线程中的代码之前完成执行。但是,这在iPhone 12上的iOS 15上不起作用。即使当调用runUntilDate的时间超过动画持续时间时,动画也不会完成。这似乎只在运行iOS 15的iPhone 12设备上是一个问题。在模拟器、iPhone 11设备上,甚至在具有与iPhone 12相同处理器的iPad Air 4上,一切都工作正常。在调用runUntilDate时,通常在主线程上执行的UI代码似乎不能在iOS 15 / iPhone 12上执行。
https://stackoverflow.com/questions/69312354
复制相似问题