iOS Как закрыть UIAlertView одним касанием в любом месте? - PullRequest
10 голосов
/ 24 ноября 2011

Я хочу отклонить UIAlertView в любом месте вне его одним нажатием. Я хочу показать UIAlertView без какой-либо кнопки.

У меня есть здесь стандартные коды UIAlertView, но мне нужно указать, как отменить его, если это возможно.

С UITouch? С UITapGestureRecognizer?

Спасибо.


EDIT:

в viewDidLoad

здесь инициализация alertview с именем «alert»

     if (alert)
     {
    emptyview = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,480)];
    emptyview.backgroundColor = [UIColor clearColor];
    [self.view addSubview:emptyview];
         [emptyview addSubview:alert];
    NSLog (@"emptyview is there!");

         UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
         [emptyview addGestureRecognizer:singleTap];
         [singleTap release];            
     }

Но это пустое представление вообще не отвечает и не отвечает на селектор handleSingleTap, который я немного переписал:

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [alert dismissWithClickedButtonIndex:0 animated:YES];
    [emptyview removeFromSuperview];
}

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

Я пытался:

     if (alert)
     {
    emptyview = [[UIView alloc]initWithFrame:CGRectMake(0,0,320,480)];
    emptyview.backgroundColor = [UIColor clearColor];
    [self.view addSubview:emptyview];
         [emptyview addSubview:alert];
    NSLog (@"emptyview is there!");

         UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
         [alert addGestureRecognizer:singleTap];
         [singleTap release];            
     }

Конечно, оповещение ответило на функцию handleSingleTap. Что я не так с emptyview?


ВТОРОЕ РЕДАКТИРОВАНИЕ:

В этом случае я хочу добиться небольшого представления с объяснением после выбора слова, аналогичной функции в приложении Kindle, если оно у вас есть. Может быть, я должен создать UIView вместо UIAlertView? Но маленький вид в приложении Kindle так хорош с тенью под ним, как это возможно?

Ответы [ 2 ]

10 голосов
/ 25 ноября 2011

Похоже, вы пытаетесь воссоздать "Тост" на iOS. Хорошие новости, кто-то уже сделал это. Посмотреть этот проект.

Редактировать: Не хочу использовать iToast. Мне нравится твой стиль, меньше кода. Вот что я придумаю. Казалось бы, очевидно, поскольку другие говорили, что единственный способ преодолеть модальную природу UIAlertView - это добавить суперпредставление для обработки сенсорных событий. Но вам не нужно делать это каждый раз вручную, рассмотрите подклассы UIAlertView. Попробуйте что-то вроде этого:

Редактировать: @wagashi, Спасибо, что приняли мой ответ, и спасибо за то, что setFrame: является хорошим местом для настройки размера. Ваш код делает очень похожее на тост маленькое предупреждение, однако, когда я попробовал его, я обнаружил, что если сообщение было слишком длинным, представление, казалось, разваливалось. Поэтому я изменил setFrame:, чтобы просто уменьшить размер оповещения примерно на размер одной кнопки и оставаться в центре экрана. Чтобы класс точно ответил на заголовок вопроса «iOS Как закрыть UIAlertView одним касанием в любом месте?»

NoButtonAlertView.h

#import <UIKit/UIKit.h>
@interface _NoButtonAlertViewCover : UIView
@property (nonatomic,assign) UIAlertView *delegate;
@end
@interface NoButtonAlertView : UIAlertView
-(id)initWithTitle:(NSString *)title message:(NSString *)message;
@end

NoButtonAlertView.m

#import "NoButtonAlertView.h"
@implementation _NoButtonAlertViewCover
@synthesize delegate = _delegate;
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [self removeFromSuperview];
    [_delegate dismissWithClickedButtonIndex:0 animated:YES];
}
@end
@implementation NoButtonAlertView
-(void)show{
    [super show];
    _NoButtonAlertViewCover *cover = [[_NoButtonAlertViewCover alloc] initWithFrame:[UIScreen mainScreen].bounds];
    cover.userInteractionEnabled = YES;
    cover.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:.01];
    cover.delegate = self;
    [self.superview addSubview:cover];
}
-(id)initWithTitle:(NSString *)title message:(NSString *)message{
    if ((self = [super initWithTitle:title message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:nil, nil])){
    }
    return self;
}
- (void)setFrame:(CGRect)rect {
    // Called multiple times, 4 of those times count, so to reduce height by 40
    rect.size.height -= 10;
    self.center = self.superview.center;
    [super setFrame:rect];
}
@end

С помощью этого простого подкласса UIAlertView и его подкласса UIView для обложки вы можете использовать его так же просто, как и стандартный UIAlertView. Вот так:

NoButtonAlertView *alert = [[NoButtonAlertView alloc] initWithTitle:@"Hello" message:@"I am the very model of a modern major general; I'm information, vegitable, animal, and mineral."];
[alert show];

даст:

Custom AlertView

3 голосов
/ 24 ноября 2011

После показа UIAlertView добавьте в свой контроллер представления (или даже окно) новый пустой UIView с полным размером экрана. Прикрепить к этому взгляду UITapGestureRecognizer

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[view addGestureRecognizer:singleTap];
[singleTap release];

Теперь в методе handleSingleTap вы можете закрыть UIAlertView и удалить это представление из окна

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [myAlert dismissWithClickedButtonIndex:0 animated:YES];
    [view removeFromSuperView];
}
...