簡體   English   中英

在 UIAlertController 外部點擊時如何關閉 UIAlertController?

[英]How to dismiss UIAlertController when tap outside the UIAlertController?

UIAlertController UIAlertController

我可以添加UIAlertAction樣式UIAlertActionStyleCancel來關閉UIAlertController

但我想添加當用戶在UIAlertController UIAlertController關閉的功能。 怎么做? 謝謝你。

如果您要定位iOS> 9.3並使用Swift並且preferredStyle為Alert的設備 ,則可以使用以下代碼段:

func showAlertBtnClicked(sender: UIButton) {
    let alert = UIAlertController(title: "This is title", message: "This is message", preferredStyle: .Alert)
    self.presentViewController(alert, animated: true, completion:{
        alert.view.superview?.userInteractionEnabled = true
        alert.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.alertControllerBackgroundTapped)))
    })
}

func alertControllerBackgroundTapped()
{
    self.dismissViewControllerAnimated(true, completion: nil)
}

隨着迅捷3:

func showAlertBtnClicked(sender: UIButton) {
    let alert = UIAlertController(title: "This is title", message: "This is message", preferredStyle: .alert)
    self.present(alert, animated: true) {
        alert.view.superview?.isUserInteractionEnabled = true
        alert.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.alertControllerBackgroundTapped)))
    }
}

func alertControllerBackgroundTapped()
{
    self.dismiss(animated: true, completion: nil)
}

使用樣式UIAlertActionStyleCancel添加單獨的取消操作。 因此,當用戶點擊外部時,您將獲得回調。

OBJ-C

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Alert Title" message:@"A Message" preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
 // Called when user taps outside
}]];

Swift 5.0

let alertController = UIAlertController(title: "Alert Title", message: "A Message", preferredStyle: .actionSheet)             
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { 
    action in
         // Called when user taps outside
}))

Swift,Xcode 9

使用取消按鈕關閉AlertController

為你的alertController提供動作,其中UIAlertAction的風格是.cancel

let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)

使用此方法當用戶點擊取消操作按鈕以及alertController外部時,alertController將被解除。

如果您不希望用戶在alertController外部觸摸后解除alertController,請在當前方法的完成閉包中禁用alertController的第一個子視圖的用戶交互。

self.present(alertController, animated: true) {
     alertController.view.superview?.subviews[0].isUserInteractionEnabled = false
    }

在Controller視圖外部的touchup上關閉AlertController

如果您不想在控制器視圖中使用取消按鈕,並且想要在控制器視圖外部進行用戶修改時關閉控制器,請執行此操作

self.present(alertController, animated: true) {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissAlertController))
        alertController.view.superview?.subviews[0].addGestureRecognizer(tapGesture)
}

@objc func dismissAlertController(){
    self.dismiss(animated: true, completion: nil)
}

如果您使用的是Swift

使用addAction(_:)style:UIAlertActionStyle.Cancel添加動作style:UIAlertActionStyle.Cancel

當點擊按鈕或框架外時,將調用`處理程序。

var alertVC = UIAlertController(...) // initialize your Alert View Controller

        alertVC.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: {
            (alertAction: UIAlertAction!) in
            alertVC.dismissViewControllerAnimated(true, completion: nil)
        }))

Objective-C

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:...];


[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
   [alertVC dismissViewControllerAnimated:YES completion:nil];
}]];

斯威夫特4:

當用戶點擊使用UIAlertController創建的操作表外部時,關閉操作表

代碼片段:

// Declare Action Sheet reference
var actionSheet: UIAlertController!

// Init and Show Action Sheet
func showActionSheetClicked(sender: UIButton) {

    // Init Action Sheet
    actionSheet = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet)

    self.present(actionSheet, animated: true) {
        // Enabling Interaction for Transperent Full Screen Overlay
        self.actionSheet.view.superview?.subviews.first?.isUserInteractionEnabled = true

        // Adding Tap Gesture to Overlay
        self.actionSheet.view.superview?.subviews.first?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.actionSheetBackgroundTapped)))
    }
}

// To dismiss Action Sheet on Tap
@objc func actionSheetBackgroundTapped() {
    self.actionSheet.dismiss(animated: true, completion: nil)
}

Obj-C中最簡單的方法:

UIAlertController *alert = [UIAlertController alertControllerWithTitle: ...
[self presentViewController:alert animated:YES completion:^{
                                       [alert.view.superview addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(alertControllerBackgroundTapped)]];
                                   }];

然后:

- (void)alertControllerBackgroundTapped
{
    [self dismissViewControllerAnimated: YES
                             completion: nil];
}
- (void)addBackgroundDismissTapForAlert:(UIAlertController *)alert {
    if (!alert.view.superview) {
        return;
    }
    alert.view.superview.userInteractionEnabled = YES;
    [alert.view.superview addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(alertControllerBackgroundTapped)]];
    for (UIView *subV in alert.view.superview.subviews) {
        if (subV.width && subV.height) {
            subV.userInteractionEnabled = YES;
            [subV addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(alertControllerBackgroundTapped)]];
        }
    }
}
- (void)alertControllerBackgroundTapped {

    [self dismissViewControllerAnimated: YES
                         completion: nil];
}
    UIView *alertView = self.alertController.view;
UIView *superPuperView = self.alertController.view.superview;
CGPoint tapCoord = [tap locationInView:superPuperView];
if (!CGRectContainsPoint(alertView.frame, tapCoord)) {
    //dismiss alert view
}

最簡單的方法:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self button];

}

- (void) button {
    UIButton * AlertButton = [UIButton buttonWithType:UIButtonTypeSystem];
    [AlertButton setTitle:@"Button" forState:UIControlStateNormal];
    AlertButton.frame = CGRectMake((self.view.frame.size.width/2) - 50 , (self.view.frame.size.height/2) - 25, 100, 50);
    [AlertButton addTarget:self action:@selector(Alert) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:AlertButton];
}

- (void)Alert {
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Alert Title" message:@"Alert Message" preferredStyle:UIAlertControllerStyleAlert];
    [self presentViewController: alert animated: YES completion:^{ alert.view.superview.userInteractionEnabled = YES; [alert.view.superview addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(DismissAlertByTab)]]; }];
}

- (void)DismissAlertByTab
{
    [self dismissViewControllerAnimated: YES completion: nil];
}

如果您查看調試警報的超級視圖,您會發現它不像在_UIAlertControllerView的UITransitionView中添加點擊手勢識別器那么簡單。您可以這樣做

[presenter presentViewController:alertController animated:YES completion:^{
    NSArray <UIView *>* superviewSubviews = alertController.view.superview.subviews;
    for (UIView *subview in superviewSubviews) {
        if (CGRectEqualToRect(subview.bounds, weakSelf.view.bounds)) {
            [subview addSingleTapGestureWithTarget:weakSelf action:@selector(dismissModalTestViewController)];
        }
    }
}];

在 iOS 15 上, UIAlertController的視圖層次結構似乎再次發生了變化。 它顯示為包含控制器本身的新UIWindow 因此,為了在外面關閉水龍頭:

present(alertController, animated: true) { [weak self] in
    guard let self = self else { return }

    let dismissGesture = UITapGestureRecognizer(target: self, action: #selector(self.shouldDismiss))

    self.alertController.view.window?.isUserInteractionEnabled = true
    self.alertController.view.window?.addGestureRecognizer(dismissGesture)
}

對於shouldDismiss函數:

@objc private func shouldDismiss() {
    alertController.dismiss(animated: true)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM