在 Swift 中点击返回键时如何关闭 UIAlertController?
Posted
技术标签:
【中文标题】在 Swift 中点击返回键时如何关闭 UIAlertController?【英文标题】:How do I dismiss a UIAlertController when the return key is tapped in Swift? 【发布时间】:2018-04-19 15:51:23 【问题描述】:我有一个带有两个按钮和一个文本字段的 UIAlertController。当点击保存按钮时,将执行转场。我还在textFieldShouldReturn
中设置了返回键来执行此操作。但是,当点击返回键时,警报控制器不会关闭。它向上移动到视图的左上角,并在返回视图时导致动画挂起。我还尝试使用myAlertController.dismiss(animated: false, completion: nil)
关闭警报控制器,但这会引发“尝试在视图不在窗口层次结构中的 UIAlertController 上呈现 UINavigationController”错误。当点击返回键并仍然执行 segue 时,如何关闭警报控制器?谢谢。
import UIKit
import CoreData
var albumNameFromTextfield: String = ""
class AlbumViewController: UIViewController, UITextFieldDelegate
// MARK: - Properties
@IBOutlet weak var albumCollectionView: UICollectionView!
@IBOutlet weak var noAlbumsView: UIView!
var albums: [NSManagedObject] = []
let newAlbumAlert = UIAlertController(title: "Create New Album", message: "Enter a name for your new album.", preferredStyle: UIAlertControllerStyle.alert)
// MARK: - Actions
@IBAction func unwindToAlbumsScreen(sender: UIStoryboardSegue)
@IBAction func newAlbumTapped(_ sender: UIBarButtonItem)
createNewAlbum()
func createNewAlbum()
let nAA = newAlbumAlert
present(nAA, animated: true, completion: nil)
// Alert controller setup
func createNewAlbumAlert()
let saveAction = UIAlertAction(title: "Save", style: .default, handler: (action) in
guard let textField = self.newAlbumAlert.textFields?[0],
let nameToSave = textField.text else
return
print("Album name has been inputted; save button tapped.")
self.save(name: nameToSave)
self.albumCollectionView.reloadData()
self.performSegue(withIdentifier: "showNewAlbumViewController", sender: self)
)
newAlbumAlert.addTextField (textField: UITextField) in
textField.placeholder = "Album Name"
textField.keyboardType = .default
textField.autocorrectionType = .default
textField.returnKeyType = .done
textField.delegate = self
textField.enablesReturnKeyAutomatically = true
newAlbumAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
newAlbumAlert.addAction(saveAction)
//Text field functions
func textFieldDidBeginEditing(_ textField: UITextField)
self.newAlbumAlert.actions[1].isEnabled = false
textField.text = ""
func textFieldDidEndEditing(_ textField: UITextField)
albumNameFromTextfield = textField.text!
print("Album name for nav title set.")
func textFieldShouldReturn(_ textField: UITextField) -> Bool
let TFNameToSave = textField.text
self.save(name: TFNameToSave!)
self.albumCollectionView.reloadData()
textField.resignFirstResponder()
self.performSegue(withIdentifier: "segueForTF", sender: self)
print("Album name has been inputted; return button tapped.")
return true
@objc func editingChanged(_ textField: UITextField)
if textField.text?.count == 1
if textField.text?.first == " "
textField.text = ""
return
guard
let alertControllerText = newAlbumAlert.textFields![0].text, !alertControllerText.isEmpty
else
newAlbumAlert.actions[1].isEnabled = false
return
newAlbumAlert.actions[1].isEnabled = true
// ViewDidLoad and ViewWillAppear
override func viewWillAppear(_ animated: Bool)
super.viewWillAppear(animated)
//Core Date functions
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else
return
let managedContext =
appDelegate.persistentContainer.viewContext
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Album")
do
albums = try managedContext.fetch(fetchRequest)
catch let error as NSError
print("Could not fetch. \(error), \(error.userInfo)")
//Setup to do when the view will appear
self.albumCollectionView.reloadData()
if albums.count == 0
noAlbumsView.alpha = 1
else
noAlbumsView.alpha = 0
override func viewDidLoad()
super.viewDidLoad()
createNewAlbumAlert()
newAlbumAlert.textFields![0].addTarget(self, action: #selector(editingChanged), for: .editingChanged)
//Core Data functions
func save(name: String)
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else
return
let managedContext =
appDelegate.persistentContainer.viewContext
let entity =
NSEntityDescription.entity(forEntityName: "Album",
in: managedContext)!
let albumName = NSManagedObject(entity: entity,
insertInto: managedContext)
albumName.setValue(name, forKeyPath: "albumName")
do
try managedContext.save()
albums.append(albumName)
catch let error as NSError
print("Could not save. \(error), \(error.userInfo)")
【问题讨论】:
【参考方案1】:不要在myAlertController
上调用dismiss
,而是在你的AlbumViewController
上调用dismiss
。我在下面编辑了你的 textFieldShouldReturn
函数:
func textFieldShouldReturn(_ textField: UITextField) -> Bool
let TFNameToSave = textField.text
self.save(name: TFNameToSave!)
self.albumCollectionView.reloadData()
textField.resignFirstResponder()
// ViewController should dismiss the alert controller
dismiss(animated: true)
self.performSegue(withIdentifier: "segueForTF", sender: self)
print("Album name has been inputted; return button tapped.")
return true
来自the docs:
呈现视图控制器负责关闭视图 它呈现的控制器。
这里,presenting 视图控制器应该是AlbumViewController
,presenting 应该是myAlertController
。
希望有效!
【讨论】:
警报控制器现在关闭,但没有执行 segue。这是我得到的错误:“警告:尝试在以上是关于在 Swift 中点击返回键时如何关闭 UIAlertController?的主要内容,如果未能解决你的问题,请参考以下文章