- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
有几篇文章介绍了如何通过点击OUTSIDE 弹出窗口来关闭 Alert Controller 弹出窗口。但我想通过点击 INSIDE 弹出窗口来关闭 Alert Controller 弹出窗口。
我在 GitHub 上看到了一些类似于“Toast”的解决方案,但我只想使用 native iOS 代码来实现。
我已经在 SO 周围进行了探索,并获得了在几秒钟后解除警报的代码(例如 Android Toast):
class ViewController: UIViewController {
let alertController = UIAlertController(title: "Alert", message: "SO Awesome!", preferredStyle: .alert)
@IBOutlet var alertButton: UIButton!
@IBAction func displayAlert(_ sender: UIButton) {
self.present(alertController, animated: true, completion: {
self.perform(#selector(self.dismissAlert), with: self.alertController, afterDelay: 3)
})
}
// dismiss (close) the alert popup
@objc func dismissAlert(_ alert: UIAlertController) {
alert.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
但是如果我不想等待 3 秒弹出警告关闭怎么办?我希望能够点击弹出警报将其关闭。 (同时保留超时功能)
我发现了一些接近但不完全符合我要求的东西。所以......经过一些工作,我自己回答了这个问题,并在下面包含了一个完整的答案。
最佳答案
我在 SO 上发现的最简单的技巧似乎是添加一个 UIControl,该 UIControl 的操作目标可以在任何触摸事件上关闭 AlertController。但是 UIControl 需要一个框架 CGRect 才能正常运行。
以下是 UIControl 的要点:
let dismissControl = UIControl()
// make the dismissControl execute dismissAlert for all touch events
dismissControl.addTarget(self, action: #selector(self.dismissAlert), for: .allTouchEvents)
// NOTE: must use the bounds, not the frame for it to work
self.dismissControl.frame = self.alertController.view.bounds
// add the UIControl on top of the UIAlertControl view
self.alertController.view.addSubview(self.dismissControl)
我探索了 4 种不同的可能性:
这是一个完整的 ViewController (Xcode 9.2,Swift 4),它可以处理所有 4 种情况:
//
// ViewController.swift
// AlertDemo - Display and dismiss UIAlertControllers with UIControl (no action buttons)
// (similar to Toast on Android OS)
//
// 4 different ways to close a UIAlertController popup window:
//
// 1) Timeout - dismiss an Alert Window after a number of seconds (like Android Toast)
// 2) Tap outside the Alert Window (tap on Alert Window DOES NOT close it)
// 3) Tap the Alert Window (tap anywhere else DOES NOT close it)
// 4) Tap anywhere on the screen (on Alert Window or outside of it) to close it
//
// Created by ByteSlinger on 2018-01-19.
// Copyright © 2018 ByteSlinger. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
let alertController = UIAlertController(title: "Alert", message: "SO Awesome!", preferredStyle: .alert)
let timeoutController = UIAlertController(title: "Timeout", message: "That Alert timed out!", preferredStyle: .actionSheet)
let dismissControl = UIControl()
@IBOutlet var alertButton1: UIButton!
@IBOutlet var alertButton2: UIButton!
@IBOutlet var alertButton3: UIButton!
@IBOutlet var alertButton4: UIButton!
// display a modal popup in the middle, wait for timeout to close
@IBAction func displayAlert1(_ sender: UIButton) {
alertController.message = "You must wait for this Alert to timeout"
self.present(alertController, animated: true, completion: {
self.perform(#selector(self.timeoutAlert), with: self.alertController, afterDelay: 3)
})
}
// display a modal popup in the middle, tap outside popup to close
@IBAction func displayAlert2(_ sender: UIButton) {
alertController.message = "Tap outside this Alert to close"
self.present(alertController, animated: true, completion: {
self.dismissControl.frame = self.alertController.view.superview?.bounds ?? CGRect.zero
self.alertController.view.superview?.insertSubview(self.dismissControl, belowSubview: self.alertController.view)
self.perform(#selector(self.timeoutAlert), with: self.alertController, afterDelay: 3)
})
}
// display a modal popup in the middle, tap on or outside popup to close
@IBAction func displayAlert3(_ sender: UIButton) {
alertController.message = "Tap anywhere to close"
self.present(alertController, animated: true, completion: {
self.dismissControl.frame = self.alertController.view.superview?.bounds ?? CGRect.zero
self.alertController.view.superview?.addSubview(self.dismissControl)
self.perform(#selector(self.timeoutAlert), with: self.alertController, afterDelay: 3)
})
}
// display a modal popup in the middle, tap on popup to close
@IBAction func displayAlert4(_ sender: UIButton) {
alertController.message = "Tap on this Alert to close"
self.present(alertController, animated: true, completion: {
// important - use bounds: alertController.view.frame WILL NOT WORK
self.dismissControl.frame = self.alertController.view.bounds
self.alertController.view.addSubview(self.dismissControl)
self.perform(#selector(self.timeoutAlert), with: self.alertController, afterDelay: 3)
})
}
// close the current alert popup (middle) and display the timeout alert (bottom)
@objc func timeoutAlert(_ alertController: UIAlertController) {
if (alertController == UIApplication.shared.keyWindow?.rootViewController?.presentedViewController) {
timeoutController.message = alertController.message!
alertController.view.willRemoveSubview(self.dismissControl)
alertController.dismiss(animated: true, completion: {
self.present(self.timeoutController,animated: true, completion: {
self.perform(#selector(self.dismissTimeout), with: self.timeoutController, afterDelay: 2)
})
})
}
}
// dimiss (close) the alert popup
@objc func dismissAlert() {
// make sure there are no timeoutAlert calls waiting
NSObject.cancelPreviousPerformRequests(withTarget: self)
alertController.view.willRemoveSubview(self.dismissControl)
alertController.dismiss(animated: true, completion: nil)
}
// dimiss (close) the timeout popup
@objc func dismissTimeout(_ alert: UIAlertController) {
alert.dismiss(animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// make the dismissControl execute dismissAlert for all touch events
dismissControl.addTarget(self, action: #selector(self.dismissAlert), for: .allTouchEvents)
// make the buttons a little prettier
alertButton1.layer.cornerRadius = 32
alertButton2.layer.cornerRadius = 32
alertButton3.layer.cornerRadius = 32
alertButton4.layer.cornerRadius = 32
}
}
要使用它,只需在 IB 中创建 4 个 UIButton 并将它们连接到 @IBOutlet 变量和函数。
注意:我不得不取消执行请求,否则警报有时会被之前的超时取消。 dismissAlert()
中的这一行起到了作用:
NSObject.cancelPreviousPerformRequests(withTarget: self)
这是 GitHub 上的完整 Xcode 项目:AlertDemo
感谢 @Apoc 以及他在这篇文章中对 UIControl
的启发:UIAlertController handle dismiss upon click outside (IPad) .从 UIAlertController 边界设置 UIControl 框架是最终让它工作的原因。
关于ios - 在 iOS 中,如何通过点击 Alert 弹出窗口中的 INSIDE 来关闭 Alert Controller?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48352231/
假设我有一个表 A 和其中的函数 C 和 B,我可以通过引用自身来调用函数 C 中的表 A 函数 B 吗? A = { B = function() print("I am B
下面的代码 class Foo: bar=[sum( i^j for i in range(9) )for j in range(9)] 加注 NameError: global name '
Column( mainAxisSize: MainAxisSize.min, children: [ Container(
我正试着将按钮宽度扩展到卡内的行间,但都不起作用。我甚至不明白它为什么要断开,它说它在框约束中断开,因为它有无限的宽度
我正试着将按钮宽度扩展到卡内的行间,但都不起作用。我甚至不明白它为什么要断开,它说它在框约束中断开,因为它有无限的宽度
我正在尝试实现一个矩阵框,为了让它工作,我必须在另一个 vector 内的一个 vector 内使用一个集合。 vector > > matrix; 但是我必须在构造函数中设置 vector 的大
我在这里找到了一个类似的问题,但没有对我有用的答案: System Clipboard Vim within TMUX within SSH session 我正在使用 Gnome 终端启动 ssh
这是我的方法: 我有一个自定义 ListView,其中包含一个包含两种不同类型 View 的自定义适配器。其中之一在每个 View 中都有一个 CheckBox。 我只想在单击其中一个复选框时通知 A
我正在尝试访问一个框架内的控件,该框架位于另一个框架内的框架内。 最后(最深的)框架仅用于登录 - 我设法做到了。 问题是登录后我基本上需要回到上框点击一个按钮。出于某种原因,我不断收到错误消息: N
我一直在阅读我能找到的关于 jsoup 和属性、类、跨度等的所有问题。但是没有一个能帮助我从这个网站获取这些数据。 我正在开发一些体育软件并从网站 soccer24.com 检索比赛数据 现在我想从特
我正在尝试在神社中创建以下循环: variable: > [ {% for replaceme in list %} { 'name': "{{ "string-{{r
我正在尝试使用 jQuery Lazy Load插件,但它说 You can also use plugin for images inside scrolling container, such a
我想把来自 JTable 的对象放在它上面,所以使用 JLayeredPane 似乎很自然。然而,让它正确地绘制,正确地做标题等是非常困难的。我该怎么做才能: 滚动时显示行标题并匹配 列标题在滚动时显
背景:这是我第一次在这里发布问题,但我从阅读他人的问题和答案中学到了很多东西,非常感谢您的所有帮助!我花了几个小时研究这个问题,但找不到适合我的解决方案。下面的示例来自 MySQL website到目
我有一些代码 function getSomeInfoFromDB() { let promises = []; let order = []; $("tr").each(fu
给定相同数量的数组/对象层,每个索引指示相同的内容,嵌套数组和对象的最佳顺序是什么? 我正在制作一个基于网格的游戏,我需要存储有关每个方 block 的几条信息。我知道无法绕过多个级别的数组/对象。我
我有 3 个这样的类: public class Subject { String name; ArrayList teachers; public Subject(Strin
我总是难以混合语言,最近我开始使用 MYSQL。在这种情况下,我有这段代码: 我需要它来打印图像而不是它正在打印的链接。 http://www.google.com/s2/favicons?doma
我查看了多个数据库,但没有找到匹配或适用于我的场景的答案,所以我求助于专家,或者至少是更有经验的专家。我对 HTML 和 CSS 相当陌生。我正在尝试弄清楚如何在 ul 中定位 li,即在 ul 下的
我是一名优秀的程序员,十分优秀!