从 UITableView 更改 viewController 时将可选值显示为“nil”

Posted

技术标签:

【中文标题】从 UITableView 更改 viewController 时将可选值显示为“nil”【英文标题】:Showing optional value as 'nil' while changing the viewController from UITableView 【发布时间】:2016-07-03 14:48:23 【问题描述】:

我正在尝试将表格行中的详细信息显示到另一个 viewController 上,我想在第二个 VC 上显示三个实体。两个 UILabel 和一个 UIImageView。虽然在第一个 VC 中我可以查看,但在第二个 VC 中,它显示 'Optional("")',并且不知道如何打开它。

import UIKit


class ViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate,UITableViewDataSource, UICollectionViewDataSource, UICollectionViewDelegate 

@IBOutlet var nameForUser: UITextField!
@IBOutlet var loginButton: UIButton!

@IBOutlet var tableView: UITableView!




let allEvents = Events.allEvents
var nextScreenRow: Events!



override func viewDidLoad() 
    super.viewDidLoad()
    //nameForUser.text! = "Please Enter Name Here"
    // Do any additional setup after loading the view, typically from a nib.

    //let userName = nameForUser.text



func textFieldDidBeginEditing(textField: UITextField) 
    textField.text = ""




func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return self.allEvents.count


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCellWithIdentifier("eventsCell")!
    let event = self.allEvents[indexPath.row]
    //print(" row \(indexPath.row)")

    cell.textLabel?.text = event.eventName
    cell.imageView?.image = UIImage(named: event.imageName)
    cell.detailTextLabel?.text = event.entryType
    //cell.textLabel?.text = allEvents[indexPath.row]

    return cell


func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 


    nextScreenRow = allEvents[indexPath.row]

    let view : DetailedEventViewController = self.storyboard?.instantiateViewControllerWithIdentifier("trytry") as! DetailedEventViewController
    self.navigationController?.pushViewController(view, animated: true)

    print("Selected section \(indexPath.section), row \(indexPath.row)")
    print(nextScreenRow.eventName)

    view.eventDetails = nextScreenRow.eventName
    print(view.eventDetails)

    view.typeOfEvent = nextScreenRow.entryType
    view.myImage = UIImage(named: nextScreenRow.imageName)
  //even the 'print' is used, it is displaying here, but not in the next VC  



func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    return true


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
    return self.allEvents.count


func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 
    let sec = collectionView.dequeueReusableCellWithReuseIdentifier("eventsSec", forIndexPath: indexPath) as! GridCollectionViewCell

    let event = self.allEvents[indexPath.row]

     sec.imageView.image = UIImage(named: event.imageName)

     sec.caption.text = event.entryType

    return sec

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) 
    performSegueWithIdentifier("tryToConnect2", sender: self)







override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        if (segue.identifier == "successfulLogin")
        segue.destinationViewController as! TabController
        //let userName = nameForUser.text
        //controller.userName = userName

    





@IBAction func loginButtonWhenPressed(sender: UIButton) 
    let userName = nameForUser.text

    if userName == "" 
        let nextController = UIAlertController()
        nextController.title = "Error!"
        nextController.message = "Please enter a name"

        let okAction = UIAlertAction(title: "okay", style: UIAlertActionStyle.Default) 
            action in self.dismissViewControllerAnimated(true, completion: nil)
        

        nextController.addAction(okAction)
        self.presentViewController(nextController, animated: true, completion: nil)
    

这是我的第二个 VC:

import UIKit

class DetailedEventViewController: UIViewController 

@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var deatiledEvent: UILabel!
@IBOutlet weak var eventType: UILabel!

var eventDetails = ""
var typeOfEvent = ""
var myImage: UIImage?

override func viewDidLoad() 
    super.viewDidLoad()

    // Do any additional setup after loading the view.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


@IBAction func viewTheElemnts(sender: AnyObject) 

    deatiledEvent.text = eventDetails
    print(deatiledEvent.text)

    eventType.text = typeOfEvent
    imageView.image = myImage



我们将不胜感激。谢谢。

【问题讨论】:

能否请您从代码中删除不必要的 cmets,并缩短您发布到最相关部分的代码数量? 我已对其进行了编辑,但在“didSelectRowAtIndexPath”中存在问题。谢谢。 @shravan.sukumar:我不明白您面临的问题?你打电话给viewTheElements: IBAction 了吗?您是否在该方法中获得了正确的数据? @MidhunMP,我确实调用了该操作,但它无法正常运行。它将标签更改为空白,并且图像视图也变为空白。基本上什么都没有显示。 @shravan.sukumar:您的表格视图和详细信息页面之间是否有连接? 【参考方案1】:

您正在didSelectRowAtIndexPath 中创建DetailedEventViewController 的实例并在那里设置值。但实际上你正在使用 segue 移动到DetailedEventViewController。所以你应该在prepareForSegue: 方法中添加这些值。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)

   if (segue.identifier == "trytry")
   
       let selectedIndex = self.tableView.indexPathForCell(sender as! UITableViewCell)
       nextScreenRow     = allEvents[selectedIndex.row]
       let view          = segue.destinationViewController as! DetailedEventViewController    
       view.eventDetails = nextScreenRow.eventName
       view.typeOfEvent  = nextScreenRow.entryType
       view.myImage      = UIImage(named: nextScreenRow.imageName)
   

【讨论】:

在那之后你要求我做的事情,在我做的“prepareForSegue”方法中,显示“致命错误:nil found wile unwrapping optional” @shravan.sukumar:你在哪条线上遇到了崩溃? 行'view.eventDetails = nextScreenRow.eventName' 但是,我已经在'didSelectRowAtIndexPath'中定义了'nextScreenRow',并且不允许我在这个函数中定义它。 @shravan.sukumar:不允许定义是什么意思?【参考方案2】:

像这样解开你的 eventName :

view.eventDetails = nextScreenRow.eventName! as String 
print(view.eventDetails) view.typeOfEvent = nextScreenRow.entryType 
view.myImage = UIImage(named: nextScreenRow.imageName) 
self.navigationController?.pushViewController(view, animated: true

【讨论】:

还是不行,在运行框中显示'Optional("")'。

以上是关于从 UITableView 更改 viewController 时将可选值显示为“nil”的主要内容,如果未能解决你的问题,请参考以下文章

从 UITableView didSelectRowAtIndexPath 检测 UISegmentedControl 中的选择更改

UITableView 在从纵向旋转到横向再回到纵向时会更改大小

从 UITableView 中删除行会更改存储在其他行中的信息

从 UITableView 更改 viewController 时将可选值显示为“nil”

如何阻止 UITableView 单元格在视图更改时消失

DataArray 已更改,但在 UITableView 上不显示新数据 [关闭]