【问题标题】:Set First Responder in MFMailComposeViewController?在 MFMailComposeViewController 中设置第一响应者?
【发布时间】:2023-03-24 21:24:01
【问题描述】:

我正在使用 Apple 的 MailComposer 示例应用程序从我的应用程序中发送电子邮件(OS 3.0 功能)。是否可以使用 MFMailComposeViewController 将 To、Subject 或 Body 字段设置为第一响应者?

换句话说,行为将是:用户按下一个显示邮件视图的按钮(presentModalViewController)。显示邮件视图时,光标会放在其中一个字段中,键盘会打开。

我注意到 MFMailComposeViewController 文档说:

"重要提示:邮件撰写界面本身不可定制,不得由您的应用程序修改。另外,在呈现该界面后,您的应用程序不得再对邮件内容进行任何更改。用户仍然可以使用界面编辑内容,但忽略编程更改。因此,您必须在呈现界面之前设置内容字段的值。”

但是,我不关心自定义界面。我只想设置 firstResponder。有什么想法吗?

【问题讨论】:

    标签: iphone email iphone-sdk-3.0 mfmailcomposeviewcontroller


    【解决方案1】:

    您可以让这些字段成为第一响应者。

    如果你将以下方法添加到你的类中......

    //Returns true if the ToAddress field was found any of the sub views and made first responder
    //passing in @"MFComposeSubjectView"     as the value for field makes the subject become first responder 
    //passing in @"MFComposeTextContentView" as the value for field makes the body become first responder 
    //passing in @"RecipientTextField"       as the value for field makes the to address field become first responder 
    - (BOOL) setMFMailFieldAsFirstResponder:(UIView*)view mfMailField:(NSString*)field{
        for (UIView *subview in view.subviews) {
    
            NSString *className = [NSString stringWithFormat:@"%@", [subview class]];
            if ([className isEqualToString:field])
            {
                //Found the sub view we need to set as first responder
                [subview becomeFirstResponder];
                return YES;
            }
    
            if ([subview.subviews count] > 0) {
                if ([self setMFMailFieldAsFirstResponder:subview mfMailField:field]){
                    //Field was found and made first responder in a subview
                    return YES;
                }
            }
        }
    
        //field not found in this view.
        return NO;
    }
    

    然后,在您展示 MFMailComposeViewController 后,将 MFMailComposeViewController 的视图与您想成为第一响应者的字段一起传递给函数。

    MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
    mailComposer.mailComposeDelegate = self;
    
    /*Set up the mail composer*/
    
    [self presentModalViewController:mailComposer animated:YES];
    [self setMFMailFieldAsFirstResponder:mailComposer.view mfMailField:@"RecipientTextField"];
    [mailComposer release];
    

    【讨论】:

    • 优秀 - 花了几个小时试图找到一些东西来做到这一点。只需将 RecipientTextField 更改为 MFRecipientTextField 即可工作。这可以用于 App Store 提交,还是被视为未记录的 API?
    • 我不确定这是否可以用于 App Store 提交,我只将它用于内部应用程序。
    • 嗨,上面的解决方案对我不起作用,当我在方法中打印它们时,它只显示 UINavigationTransitionView、UILayoutContainerView、UIButtonLabel、UINavigationButton 等作为类名。它没有提供一个名为 MFRecipientTextField 等的子视图类。知道有什么问题吗?
    • 顺便说一句,收件人视图是“MFMailComposeRecipientView”而不是“RecipientTextField”,至少对我而言。
    • 我相信由于使用了远程视图控制器,这种技术在 iOS 6 中不再适用。我很想知道实现这一目标的最新方法。
    【解决方案2】:

    在 iOS 6 中,不再可能在任何文本字段 AFAICT 上设置第一响应者。导航视图层次结构最终会显示一个 UIRemoteView,并且这里的子视图被混淆了。

    【讨论】:

      【解决方案3】:

      您可以尝试在控制器本身上调用 becomeFirstResponder。如果这不起作用,您可以尝试在调试器中获取邮件撰写视图的子视图列表,直到找到熟悉的文本字段或文本视图,然后您可以专门编写代码以在代码中设置响应者状态,这可能看起来像这个(我不知道这是否可行,但这是一个例子):

      [[[[mailcomposer.view.subviews objectAtIndex:3] subviews] objectAtIndex:2] becomeFirstResponder]
      

      【讨论】:

        【解决方案4】:

        我喜欢简化代码并使其易于理解。 只需将以下代码放在后面:
        [self presentModalViewController:mailComposer Animation:YES];

        for (UIView *subview in mailComposer.view.subviews) {
           NSString *className = [NSString stringWithFormat:@"%@", [subview class]];
           //NSLog(@"%@", className); // list the views - Use this to find another view
           //The view I want to set as first responder: "_MFMailRecipientTextField"
           if ([className isEqualToString:@"_MFMailRecipientTextField"]){
           [subview becomeFirstResponder];
           break; // Stop search.
          }
        }
        

        【讨论】:

        • 这不起作用,因为递归是向下导航视图层次结构所必需的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-13
        • 2021-04-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多