iPhone UIDocumentInteractionController presentOpenInMenuFromRect 取消按钮没有响应

Posted

技术标签:

【中文标题】iPhone UIDocumentInteractionController presentOpenInMenuFromRect 取消按钮没有响应【英文标题】:iPhone UIDocumentInteractionController presentOpenInMenuFromRect cancel button does not respond 【发布时间】:2011-08-10 17:29:54 【问题描述】:

当在 iPhone4 和 iPad2(都在 ios 4.3.5 中运行)中执行“presentOpenInMenuFromRect”时,我观察到了不同的行为。在 iPad2 中,它显示一个下拉列表,其中包含可以打开特定文件的所有应用程序,并且工作正常;但是,在 iPhone4 中,它也显示了一个下拉列表(并且也可以正常工作),但在下拉列表的末尾有一个“取消”按钮,它似乎处于非活动状态。

在 iPad2 中不会出现这个问题,因为“取消”按钮没有出现,只出现下拉列表,当我点击与下拉列表不同的另一个区域时,该列表关闭;这是期望的行为。

我的意思是说 iPhone/iPhone4 中的“取消”按钮似乎处于非活动状态是:当我触摸它时,什么也没有发生!好吧,更具体地说,如果我在短时间内触摸它几次,那么,迟早,“取消”按钮似乎会响应(它的颜色从灰色变为蓝色),然后是下拉列表真的关门了;这是期望的行为。

我通过以下方式使用“presentOpenInMenuFromRect”:我已经实现了一个“保存”按钮,默认情况下它是隐藏的;但是,在方法“-(void)webViewDidFinishLoad:(UIWebView *)webView”中,我检测到 URL 的“路径扩展名”,如果它具有“.pdf”扩展名,则显示“保存”按钮;那就是:

-  (void)webViewDidFinishLoad:(UIWebView *)webView

    if ([[[myWebViewOL.request.URL.absoluteString pathExtension] lowercaseString] isEqualToString:@"pdf"])
    
        saveFile0L.hidden = NO;
    

而与“保存”按钮(saveFile0L)相关的“动作”是下面的方法“saveFile”:

[saveFile0L addTarget:self action:@selector(saveFile) forControlEvents:UIControlEventTouchUpInside];

其中“saveFile”的代码如下:

- (void) saveFile

    //Do not worry about "FileManager" is only a singleton class
    //which I have defined in order to implement some common methods
    //and one of them is "saveFile:(UIWebView*) withUIView:(UIView*)
    [[FileManager sharedInstance] saveFile:myWebView withUIView:self.view];

而“saveFile:(UIWebView*)myWebView withUIView:(UIView*)self.view”的代码如下:

- (void) saveFile:(UIWebView*)webView withUIView:(UIView*)view

    NSString* fileName  = [[NSFileManager defaultManager] displayNameAtPath:webView.request.URL.absoluteString];
    NSURL* fileurl = [NSURL URLWithString:webView.request.URL.absoluteString];
    NSData* data = [NSData dataWithContentsOfURL:fileurl];
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* docsDirectory = [paths objectAtIndex:0];
    NSString* filePath = [docsDirectory stringByAppendingPathComponent:fileName];
    [data writeToFile:filePath atomically:YES];
    NSURL* url = [NSURL fileURLWithPath:filePath];
    //UIDocInteractionController API gets the list of devices that support the file type
    docController = [UIDocumentInteractionController interactionControllerWithURL:url];
    [docController retain];
    //Note:[docController presentOpenInMenuFromRect:CGRectZero inView:view animated:YES]
    //presents a drop down list of the apps that support the file type,
    //clicking on an item in the list will open that app while passing in the file.
    //Note: [[UIApplication sharedApplication] canOpenURL:fileurl]
    //will return YES if there is an app that can handle the specific file
    BOOL isValid = ([[UIApplication sharedApplication] canOpenURL:fileurl] &&
                    [docController presentOpenInMenuFromRect:CGRectZero inView:view animated:YES]);
    if (!isValid)
    
        [self showAlertSaveFileError:fileName];
    

目前,我不知道如何使下拉列表末尾仅出现在iPhone(而不是iPad)中的“取消”按钮正常工作。

提前致谢,

【问题讨论】:

我在使用 UIDocumentInteractionController 时显示的 iPhone 应用程序列表存在这个问题。我为我的项目使用了嵌入在 UITabBarController 中的 UINavigationContoller,我注意到当我显示 UIDocumentInteractionController 列表时,我无法单击取消按钮来关闭列表。在点击取消按钮区域后,我发现我错误地设置了“...FromRect:CGRect inView:...”参数。尝试点击取消按钮上方和下方的区域...如果这会关闭列表,则根据需要更改视图或 CGRect。 【参考方案1】:
BOOL isValid = ([[UIApplication sharedApplication] canOpenURL:fileurl] &&
                    [docController presentOpenInMenuFromRect:CGRectZero inView:view animated:YES]);

尝试将view inView:view 更改为inView:self.view.window

【讨论】:

【参考方案2】:

这是我的错;终于可以解决问题了。

错误是使用“self.view”并将其作为函数“presentOpenInMenuFromRect”的参数传递

[docController presentOpenInMenuFromRect:CGRectZero inView:view Animation:YES]

然而,这个“视图”(self.view)并不适合处理触摸事件;由于在 Xcode 控制台中显示了以下警告,因此可以注意到此错误:

2011-08-17 18:12:56.389 MyApplication[287:707] Presenting action sheet clipped by its superview. Some controls might not respond to touches. On iPhone try -[UIActionSheet showFromTabBar:] or -[UIActionSheet showFromToolbar:] instead of -[UIActionSheet showInView:].

这条消息给了我线索,我已经通过以下方式修改了代码:

新的正确的代码是:

- (void) saveFile:(UIWebView*)webView

    NSString* fileName  = [[NSFileManager defaultManager]  displayNameAtPath:webView.request.URL.absoluteString];
    #if DEBUG
    NSLog(@"<%p %@: %s line:%d> File name:%@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __PRETTY_FUNCTION__, __LINE__, fileName);
    #endif
    NSURL* fileurl = [NSURL URLWithString:webView.request.URL.absoluteString];
    NSData* data = [NSData dataWithContentsOfURL:fileurl];
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* docsDirectory = [paths objectAtIndex:0];
    NSString* filePath = [docsDirectory stringByAppendingPathComponent:fileName];
    [data writeToFile:filePath atomically:YES];
    NSURL* url = [NSURL fileURLWithPath:filePath];
    //UIDocInteractionController API gets the list of devices that support the file type
    docController = [UIDocumentInteractionController interactionControllerWithURL:url];
    [docController retain]; //Very important, if "retain" is not called, the application crashes
    //Present a drop down list of the apps that support the file type,
    //clicking on an item in the list will open that app while passing in the file.
    BOOL isValid = [docController presentOpenInMenuFromRect:CGRectZero inView:webView animated:YES]; //Using "webView" instead of "self.view"
    if (!isValid)
    
        [self showAlertSaveFileError:fileName]; //Shows an alert message
    

也就是说,将视图“webView”(这是一个 UIWebView)传递给方法“presentOpenInMenuFromRect:inView:animated:”,而不是“self.view”。

【讨论】:

就可以了,你也可以按照我之前的回答使用self.view.window

以上是关于iPhone UIDocumentInteractionController presentOpenInMenuFromRect 取消按钮没有响应的主要内容,如果未能解决你的问题,请参考以下文章

在 iphone 5 和 iphone 6 中动态设置字体大小

Surface Pro4链接不上iphone手机的热点

iphone13和12外观的区别 iphone13和iphone12对比哪个好

为 iPhone 和 iPhone 4 开发之间有啥变化?

iPhone 5 与 iPhone 4 的图像命名

设置图像以适合 iPhone 5 和 iPhone 6