0

There is a CollectionView with a couple items. I am trying to pop a alert message with textfield to create a new file when the item is selected.

However, when the last instruction (self.present(....)) is executed, an error message : "fatal error: unexpectedly found nil while unwrapping an Optional value" occurred.

I have also tried the code from : How to present an AlertView from a UICollectionViewCell but it does not work as well.

self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)

Is it possible to do that? How can I solve this problem? Thanks.

func addFile(){    
let alert = UIAlertController(title: "New file name:", message: "", preferredStyle: .alert)
    alert.addTextField{
        (textField: UITextField!) -> Void in
        textField.placeholder=""
    }
    let cancelAction = UIAlertAction(title: "Cancel",style: .cancel, handler: nil)
    alert.addAction(cancelAction)
    let createAction = UIAlertAction(title: "Create" ,style: .default){
        (action:UIAlertAction!) -> Void in
        let fileName = (alert.textFields?.first)! as UITextField
        print(fileName.text)
    }
    alert.addAction(createAction)
    self.present(alert, animated: true, completion: nil)
}

EDIT: solved.

i modified the last line to UIApplication.shared.keyWindow?.rootViewController?.presentedViewController?.present(alert,animated: true, completion: nil) and the alert box pop finally.

szeto1121
  • 13
  • 7

3 Answers3

2

I recommend you to use delegate. and I will demo some code to you. first create prototype

protocol AlertViewDelegate {
      func alertSending(sender: UIAlertController)
}

than you implement in uicollectionviewcell class by

var delegate: AlertViewDelegate?
func actionMethod() { 
     let alert = UIAlertController(title: "New file name:", message: "", preferredStyle: .alert)
     alert.addTextField{
    (textField: UITextField!) -> Void in
     textField.placeholder=""
}
     let cancelAction = UIAlertAction(title: "Cancel",style: .cancel, handler: nil)
     alert.addAction(cancelAction)
     let createAction = UIAlertAction(title: "Create" ,style: .default){
    (action:UIAlertAction!) -> Void in
        let fileName = (alert.textFields?.first)! as UITextField
        print(fileName.text)
     }
     alert.addAction(createAction)
     delegate?.alertSending(sender: alert)
}

finally you go to your uicollectionviewcontroller class than extends delegate

extension ViewCollectionViewController: AlertViewDelegate {
func alertSending(sender: UIAlertController) {
    self.present(sender, animated: true, completion: nil)        
}

question please comment. hope it works for you. enjoy!

Leang Socheat
  • 1,156
  • 2
  • 12
  • 23
0

You have problems in these two lines:

let fileName = (alert.textFields?.first)! as UITextField
print(fileName.text)

Change them to these lines:

let fileName = alert.textFields?.first?.text
print(fileName!)
nayem
  • 7,285
  • 1
  • 33
  • 51
  • No. It's working fine. See [here](http://imgur.com/a/G6uUT). You might have some problems elsewhere – nayem Jun 14 '17 at 07:15
  • however, the alert is called by selecting a collection view cell, is it the same one as yours? Thanks. – szeto1121 Jun 14 '17 at 07:32
  • Yes. I've tried it with a project where I used `CollectionView` and it works just fine. [Here](http://imgur.com/a/r0QLn) – nayem Jun 14 '17 at 08:07
  • since the collectionview I am using is not created on the storyboard, it is just created by a class. I don't know if it matters. – szeto1121 Jun 14 '17 at 08:26
  • Show the `collectionView(_:didSelectItemAt:)` method's implementation – nayem Jun 14 '17 at 08:30
  • func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let setting = settings[indexPath.item] UIView.animate(withDuration:0.5){ self.blackView.alpha = 0 if let window = UIApplication.shared.keyWindow { self.collectionView.frame = CGRect(x: 0, y: window.frame.height, width: self.collectionView.frame.width, height: self.collectionView.frame.height) } } if setting.name == .addFile{ ViewController().addFile() } – szeto1121 Jun 14 '17 at 08:34
  • Well. So where did you put your `UIAlertCotroller` showing code? – nayem Jun 14 '17 at 08:41
  • the func addFIle in the ViewController.swift – szeto1121 Jun 14 '17 at 08:41
  • No. I just wanted to know ___where did you put the code that you added in your question___? Please edit your question with the enclosing block of that code. – nayem Jun 14 '17 at 08:43
  • I suspect that you have problem in `if setting.name == .addFile`. What's the data structure of your `setting` variable? – nayem Jun 14 '17 at 08:56
  • setting is a NSObject class with a string called name – szeto1121 Jun 14 '17 at 09:11
  • So how are you comparing `setting.name` to `.addFile`? How even are you getting past this line without Xcode editor error? – nayem Jun 14 '17 at 09:14
  • as the name is an enumeration of string, and addFile is one of the case, so it can get past the editor – szeto1121 Jun 14 '17 at 09:17
  • Well, I'm done. Can't help you with anything without having the source code. – nayem Jun 14 '17 at 09:20
  • Sorry, I cannot share the whole source code. Anyway, thanks for all the help and sorry again if it wastes your time. – szeto1121 Jun 14 '17 at 09:25
0

Replace only the part with createAction

let createAction = UIAlertAction(title: "Create" ,style: .default){
     (action:UIAlertAction!) -> Void in
     guard let textField = alert.textFields?.first,
         let fileName = textField.text else { return }
         print(fileName)
}
alert.addAction(createAction)
ankis
  • 1
  • 1