我有一个带有两个按钮和一个文本字段的UIAlertController。点击保存按钮时,执行segue。我还在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)")
}
}
}
答案 0 :(得分:2)
不要在dismiss
上拨打myAlertController
,而是在dismiss
上拨打AlbumViewController
。我已在下面编辑了您的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:
呈现视图控制器负责解除视图 它呈现的控制器。
此处,呈现视图控制器应为AlbumViewController
,呈现为myAlertController
。
希望有效!