Кнопка отмены MFMailComposeViewController (возможно, лист действий) замораживает представление

Я уже встречал несколько вопросов, например this но из-за отсутствия принятого ответа, а также из-за того, что все было реализовано по мере необходимости, я все еще сталкиваюсь со следующей проблемой: я отображаю почтовый композитор, но при нажатии кнопки «Отмена» вид композитора зависает. Я думаю, это связано с тем, что лист черновика «Сохранить / удалить» отображается вне видимого фрейма. Да, я установил mailComposeDelegate на контроллер представления представления и прочитал несколько похожих вопросов, где пользователь не обработал делегат (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error, чтобы уволить композитора при отмене. Я тоже справился с этим, но, похоже, я не могу понять, почему лист действий не отображается в видимой области экрана в версии моего универсального приложения для iPhone. Рамка представления контроллера представления, модально представляющего составителя почты как NSLogged, составляет (0,0,320,480). Мое приложение универсально, и составитель почты отлично работает на iPad. Ниже приведен снимок экрана, как выглядит представление композитора, работающее на iPhone Simulator 5.1: -

enter image  описание здесь
Вот код для отображения композитора:

-(IBAction)mailButtonPressed:(id)sender {

    MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
    controller.mailComposeDelegate = self;
    [controller setSubject:@"Subject"];
    [controller setMessageBody:@"Test" isHTML:YES];
    [controller setToRecipients:nil];

    if(controller) {
        [self presentModalViewController:controller animated:YES];
        [controller release];
    }
}

- (void)mailComposeController:(MFMailComposeViewController*)controller 
          didFinishWithResult:(MFMailComposeResult)result
                        error:(NSError*)error 
{ 
    [self dismissModalViewControllerAnimated:YES];
}

person akdsouza    schedule 13.12.2012    source источник
comment
Можете ли вы опубликовать код того, как вы представляете составителя почты?   -  person Eric    schedule 13.12.2012
comment
Я отредактировал вопрос, добавив код   -  person akdsouza    schedule 13.12.2012
comment
Пожалуйста, также разместите код для метода делегата didFinishWithResult   -  person Atif Azad    schedule 13.12.2012
comment
Попробуйте распечатать ошибку: NSLog (@Error:% @, error);   -  person Eric    schedule 13.12.2012
comment
Делегат не запускается для этого! Предположительно из-за того, что обычно появляется лист черновика «Сохранить / отклонить».   -  person akdsouza    schedule 13.12.2012
comment
Хорошо, попробуйте прокомментировать строку выпуска контроллера ... хотите посмотреть, может быть, он будет отключен, прежде чем отклонять   -  person Eric    schedule 13.12.2012
comment
Я пробовал это, но безуспешно :(   -  person akdsouza    schedule 13.12.2012
comment
Очень странно ... Я предполагаю, что это как-то связано с тем, что у вас есть универсальное приложение и что-то не так в вашей настройке ... Но я просто не могу многое узнать, не углубляясь в ваш проект. Я бы попытался, может быть, сделайте тот же подход где-нибудь в другом месте вашего приложения или в новом приложении в целом, чтобы увидеть, можете ли вы получить другие результаты   -  person Eric    schedule 13.12.2012
comment
Я пробовал с другой точки зрения. Тот, который представляет составителя почты, является одним из нескольких представлений. Попытка отобразить составитель почты в других представлениях работает правильно. Я попытался удалить и воссоздать контроллер представления «проблема», но результаты не изменились.   -  person akdsouza    schedule 13.12.2012
comment
контроллер представления, обрабатывающий метод mailButtonPressed, находится внутри контроллера навигации?   -  person Nitin Alabur    schedule 13.12.2012
comment
Вау ... Ты каждый раз парируешь мои ходы! Я сейчас в большом тупике ... Есть ли что-нибудь в контроллере представления проблемы, чем в других. Такие вещи, как: проблема vc представлена ​​модально, когда другие нет, является ли она частью стека навигации, а другие нет. Что-то должно отличаться от этого vc, чем другие   -  person Eric    schedule 13.12.2012
comment
@calvinBhai: Нет, это только контроллер представления.   -  person akdsouza    schedule 13.12.2012
comment
@ Эрик: Я знаю, что знаю. Потому что я боролся изо всех сил с этой проблемой и, кажется, проигрываю, испробовав почти все возможное! Я даже дошел до того, что заменил содержимое других представлений проблемным, за исключением добавления кода составителя почты, но все равно ничего не решает!   -  person akdsouza    schedule 13.12.2012
comment
соответствует ли ваш viewcontroller MFMailComposeViewControllerDelegate?   -  person Nitin Alabur    schedule 14.12.2012
comment
Да, это соответствует. По сути, я настроил почтовый композитор так, как это можно было бы назвать «идеальным» способом, мягко говоря.   -  person akdsouza    schedule 14.12.2012
comment
Запустите проблему, затем приостановите работу отладчика. Запустите эту команду отладчика: po [[UIApp keyWindow] recursiveDescription]. Скопируйте результат и вставьте его в свой вопрос.   -  person rob mayoff    schedule 23.12.2012
comment
Я пробовал это на iOS5.1 и iOS 6.0. Мне не удалось заставить делегата выполнить, что бы я ни пытался, независимо от того, появляется ли когда-либо сообщение об отклонении черновика. Как будто документация для метода делегата неверна. Я не думаю, что проблема в том, что отброшенный черновик находится за кадром, я думаю, что делегат не вызывается.   -  person emrys57    schedule 23.12.2012
comment
@robmayoff проблема в том, что отладчик никогда не останавливается :(   -  person akdsouza    schedule 23.12.2012
comment
@ emrys57 единственное разумное объяснение, которое я нашел для представления, которое выглядит пользовательским интерфейсом, - это лист действий, который появляется, но не отображается. Можете ли вы пролить свет на ваш сценарий, чтобы получить ту же проблему? :(   -  person akdsouza    schedule 23.12.2012
comment
Я согласен, что ваша версия выглядит так, как если бы лист действий появлялся за кадром. Однако я не вижу такого затемнения ни на iPhone (3GS, ни на 4), на котором я его пробовал. Я вижу лист действий по отклонению черновика, когда есть неотправленный отредактированный черновик, который нужно удалить. Но делегат никогда не вызывается. `MFMailComposeViewController * mailer = [[выделение MFMailComposeViewController] инициализация]; mailer.delegate = self; [self presentModalViewController: анимация почтовой программы: true]; `   -  person emrys57    schedule 23.12.2012
comment
Вы были правы, когда заподозрили подозрения. Я написал mailer.delegate = self; вместо mailer.mailComposeDelegate = self; и действительно имел неправильное определение делегата. Теперь код на обоих iPhone работает нормально. Нет затемненных представлений; все отклоняет, как ожидалось. Я начал пробовать с приложением для iPhone, и это было нормально. Я переключил его на универсальное приложение, работающее на iPhone, и это тоже было нормально.   -  person emrys57    schedule 24.12.2012
comment
Я думаю, что с UIWindow что-то не так. как вы его настраиваете? Вы должны создать его в application:didFinishLaunchingWithOptions: с помощью self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];   -  person Felix    schedule 24.12.2012
comment
точно так же и его настройка. журнал печати кадра {{0, 0}, {320, 480}}   -  person akdsouza    schedule 24.12.2012
comment
Хорошо, никто из нас не имеет ни малейшего представления, и я попытался воспроизвести это, но безуспешно. Как насчет того, чтобы поделиться всем проектом xcode и позволить нам запустить его и посмотреть, получим ли мы тот же результат? Github? И, кстати, счастливого Рождества!   -  person emrys57    schedule 25.12.2012
comment
можете ли вы вставить код функции didFinishLaunchingWithOptions класса AppDelegate ..   -  person P.J    schedule 26.12.2012
comment
У меня есть один трюк, вместо [self presentModalViewController: controller animated: YES]; используйте класс rootviewcontroller appDelegate, создав экземпляр вашего AppDelegate [[UIApplication sharedApplication] делегата] в вашем текущем классе, а затем просто заменив себя на appDelegate. (ваш класс rootviewController). Сообщите мне, если это решит вашу проблему.   -  person P.J    schedule 26.12.2012
comment
Почему ваш отладчик не останавливается? У вас должна быть возможность запустить продукт- ›Отладка-› Пауза (или нажать кнопку паузы на панели отладчика) до / после нажатия кнопки «Отмена» и запуска кода, упомянутого Робом Мэйоффом. Это может помочь вам узнать, есть ли какие-либо виды за пределами экрана.   -  person murat    schedule 26.12.2012
comment
Вы создали категорию для отмены UIActionSheet метода? Есть ли шанс, что ваш код думает, что это iPad, и пытается открыть лист действий, даже если это iPhone?   -  person Warif Akhand Rishi    schedule 27.12.2012
comment
AFAIK, на iPad лист действий появляется как всплывающее окно, а не лист действий.   -  person akdsouza    schedule 27.12.2012
comment
@Kevin ты нашел решение? Я столкнулся с той же проблемой.   -  person user-123    schedule 30.06.2013
comment
@AnatolyAnatoly Я немного отложил это в сторону, прежде чем вернулся к нему. Закончилось отображение составителя почты через rootviewcontroller, а не через текущий контроллер представления. HTH.   -  person akdsouza    schedule 01.07.2013


Ответы (6)


Почему бы не попробовать удалить код и повторить попытку, следуя онлайн-руководству, например этому:

http://iphonedevsdk.com/forum/tutorial-discussion/43633-quick-tutorial-on-how-to-add-mfmailcomposeviewcontroller.html

В таких случаях вы всегда забываете об одной простой строке кода, необходимой для работы, поэтому следование руководству помогает мне убедиться, что весь необходимый код есть.

Вместо этого попробуйте этот код:

- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    switch (result)
    {
        case MFMailComposeResultCancelled:
            NSLog(@"Mail cancelled");
            break;
        case MFMailComposeResultSaved:
            NSLog(@"Mail saved");
            break;
        case MFMailComposeResultSent:
            NSLog(@"Mail sent");
            break;
        case MFMailComposeResultFailed:
            NSLog(@"Mail sent failure: %@", [error localizedDescription]);
            break;
        default:
            break;
    }

    // Close the Mail Interface
    [self dismissViewControllerAnimated:YES completion:NULL];
}
person MacN00b    schedule 25.12.2012
comment
У меня :) из-за того, что проблема меня раздражает, я внимательно следил за тем, чтобы не пропустить что-нибудь тривиальное :) - person akdsouza; 25.12.2012
comment
Используйте контроллер вместо себя. Иначе не получится. - person Fengson; 04.02.2016

Используйте весь этот код здесь для сообщения:

.h

    #import <MessageUI/MFMailComposeViewController.h>
    @interface EmailViewController : UIViewController<MFMailComposeViewControllerDelegate>

.m

  -(IBAction)Email {

        MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
            [composer setMailComposeDelegate:self];
            if ([MFMailComposeViewController canSendMail]) {
                [composer setToRecipients:[NSArray arrayWithObjects:@"[email protected]", nil]];
                [composer setSubject:@"Idea for Basic Calculator"];
                [composer setMessageBody:@"My idea is:" isHTML:NO];
                [composer setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
                [self presentModalViewController:composer animated:YES];

    }

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
    if (error) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error with message" message:[NSString stringWithFormat:@"Error %@", [error description]] delegate:nil cancelButtonTitle:@"Try Again Later!" otherButtonTitles:nil, nil];
        [alert show];
        [self dismissModalViewControllerAnimated:YES];
    }
    else {
        [self dismissModalViewControllerAnimated:YES];
    }
}
person OnkaPlonka    schedule 28.12.2012
comment
спасибо, но проблема, по сути, не в коде, потому что, как я уже упоминал в строке комментариев к моему вопросу, код, опубликованный в вопросе, отлично работает в других представлениях. - person akdsouza; 28.12.2012

Возможно, устройство, которое вы пытаетесь, по какой-то причине не может отправлять почту.

Вы можете проверить это с помощью [MFMailComposeViewController canSendMail]

person Ismael    schedule 28.12.2012

Применить это в

-(void)displayComposerSheet

if(composer != nil) {

    [composer release];

    composer = nil;

}

После присвоения ценности этому объекту

[picker composer];
person Vishal    schedule 29.12.2012

Похоже, вы не используете автоматический подсчет ссылок (ARC). Вы слишком рано выпускаете контроллер создания почты. Отпустите его после того, как он будет закрыт.

Удалите эту строку: [релиз контроллера]

if(controller) {
    [self presentModalViewController:controller animated:YES];
    /// remove this: ---->  [controller release];
}

и отпустите этот контроллер здесь

- (void)mailComposeController:(MFMailComposeViewController*)controller 
          didFinishWithResult:(MFMailComposeResult)result
                        error:(NSError*)error 
{ 
    [self dismissModalViewControllerAnimated:YES];

    [controller release]; // <----     add this
}
person Alex L    schedule 29.12.2012

Добавьте это к своим (всем) UIViewControllers, чтобы проверить, исчерпывается ли ваш iPhone или память. Это может объяснить странное поведение, например, mailComposerSheet выпустил ваш базовый viewController, поэтому mailComposerDelegate равен нулю.

- (void)didReceiveMemoryWarning
{
  NSLog(@"didReceiveMemoryWarning");
  [super didReceiveMemoryWarning];
}
person JOM    schedule 30.12.2012