Swift segue 不会将数据传递给旧的 ViewController

Posted

技术标签:

【中文标题】Swift segue 不会将数据传递给旧的 ViewController【英文标题】:Swift segue will not pass data to old ViewController 【发布时间】:2015-07-24 15:04:34 【问题描述】:

抱歉,如果这是愚蠢的,我是编码新手。找不到与此问题相关的先前提出的问题(代码似乎是正确的)。

我正在构建一个基本的新闻提要应用程序。

在主视图控制器 FeedsTableViewController.swift 上,我有一个按钮,当它被推到 AddFeedViewController.swift 时。

在 AddFeedViewController 上,我有一个 segue 函数,应该从 UITextField(RSS 提要的网址)获取文本,然后运行一个函数 (AddNewFeed),将数据输入 TableView 单元格在 FeedsTableViewController 上。

在运行应用程序时,我能够从 FeedsTableViewController 中分离出来,但没有数据被传递到 FeedsTableViewController 中的单元格中。我知道 AddNewFeed 工作正常,因为我在 viewDidLoad 中自动运行该函数以在 Apple 的 RSS 提要中进行硬编码。

我能想到的唯一一件事是数据没有从 UITextField 中正确提取,或者没有作为参数正确输入到 AddNewFeed 中。不知道为什么这不起作用,非常感谢您的想法。

FeedsTableViewController 代码:

var feedUrl


    override func viewDidLoad() 
    super.viewDidLoad()

    AddNewFeed("http://developer.apple.com/news/rss/news.rss")




func AddNewFeed(url: String) 
    feedUrl = url
    let url : NSURL = NSURL(string: feedUrl)!


    parser = NSXMLParser(contentsOfURL: url)!
    parser.delegate = self
    parser.parse()

AddFeedViewController 代码:

class AddFeedViewController: UIViewController 

@IBOutlet weak var feedUrl: UITextField!

override func viewDidLoad() 
    super.viewDidLoad()




override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()






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

    let feedsViewController = segue.destinationViewController as! FeedsTableViewController

    feedsViewController.AddNewFeed(feedUrl.text)


这是来自 2 个类文件的代码:

FeedsTableViewController:

导入 UIKit

类 FeedsTableViewController: UITableViewController, NSXMLParserDelegate

var parser : NSXMLParser = NSXMLParser()
var feedUrl : String = String()

var feedTitle : String = String()
var articleTitle : String = String()
var articleLink : String = String()
var articlePubDate : String = String()
var parsingChannel : Bool = false
var eName : String = String()

var feeds : [FeedModel] = []
var articles : [ArticleModel] = []


override func viewDidLoad() 
    super.viewDidLoad()

    AddNewFeed("http://developer.apple.com/news/rss/news.rss")




func AddNewFeed(url: String) 
    feedUrl = url
    let url : NSURL = NSURL(string: feedUrl)!


    parser = NSXMLParser(contentsOfURL: url)!
    parser.delegate = self
    parser.parse()


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



@IBAction func retrieveNewsFeed(segue: UIStoryboardSegue)



func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject]) 

    eName = elementName
    if elementName == "channel" 
        feedTitle = String()
        feedUrl = String()
        parsingChannel = true

     else if elementName == "item" 
        articleTitle = String()
        articleLink = String()
        articlePubDate = String()
        parsingChannel = false
    



func parser(parser: NSXMLParser, foundCharacters string: String?) 
    let data = string!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())

    if(!data.isEmpty)
        if parsingChannel 
            if eName == "title" 
                feedTitle += data
            
         else 
            if eName == "title" 
                articleTitle += data
             else if eName == "link" 
                articleLink += data
             else if eName == "pubDate" 
                articlePubDate += data
            
        
    


func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) 
    if elementName == "channel" 
        let feed : FeedModel = FeedModel()
        feed.title = feedTitle
        feed.url = feedUrl
        feed.articles = articles
        feeds.append(feed)


     else if elementName == "item" 
        let article : ArticleModel = ArticleModel()
        article.title = articleTitle
        article.link = articleLink
        article.pubDate = articlePubDate
        articles.append(article)
    


// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    return feeds.count



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

    let cell = tableView.dequeueReusableCellWithIdentifier("FeedCell", forIndexPath: indexPath) as! UITableViewCell

    let feed : FeedModel = feeds[indexPath.row]
    cell.textLabel!.text = feed.title

    return cell



/*
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    // Return NO if you do not want the specified item to be editable.
    return true

*/

/*
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 
    if editingStyle == .Delete 
        // Delete the row from the data source
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
     else if editingStyle == .Insert 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        

*/

/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) 


*/

/*
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool 
    // Return NO if you do not want the item to be re-orderable.
    return true

*/


// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if segue.identifier == "ShowArticles" 
        let viewController: ArticlesTableViewController = segue.destinationViewController as! ArticlesTableViewController
        let indexPath = self.tableView.indexPathForSelectedRow()!
        let feed = feeds[indexPath.row]

        viewController.articles = feed.articles

    

    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.

/*
    if(segue.identifier == "SomeSegue")
        var articlesController = segue.destinationViewController as! ArticlesTableViewController

        // gives access to the temp variable on the destination, now its ready to fire.

        articlesController.temp = "hello there"
    
*/


AddFeedViewController:

导入 UIKit

类 AddFeedViewController: UIViewController

@IBOutlet weak var feedUrl: UITextField!

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.




// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 

    let feedsViewController = segue.destinationViewController as! FeedsTableViewController

    feedsViewController.AddNewFeed(feedUrl.text)


【问题讨论】:

我在 AddFeedController 上有一个按钮,它连接到视图控制器顶部的 Exit 图标。退出按钮与 FeedsTableViewController 中的 @IBAction 相关联。运行应用程序并点击按钮会将您从 AddFeedController 带回 FeedsTableViewController - 所以我认为按钮没问题? 【参考方案1】:

当数据源更新时,你想调用 reloadData 来更新 tableview。我认为/猜想这就是问题所在。

通常,您希望在目标视图控制器中创建一个字段,而不是直接解析它:DestinationViewController 可能尚未处于正确的生命周期中,仅供参考

【讨论】:

【参考方案2】:

在你的FeedsTableViewController 中添加一个新方法(UIStoryboardSegue 参数在这里很重要),例如:

@IBAction func dismissToFeeds(segue:UIStoryboardSegue) 
    let addViewController = segue.sourceViewController as! AddFeedViewController

    // get data from addViewController
    let data = addViewController.feedUrl.text
    println("\(data)")
    // reload table view

在情节提要中的AddFeedViewController 控制标签中,从用于关闭视图的按钮到展开图标:

第三个“退出”图标并选择dismissToFeeds 操作。

【讨论】:

已经这样做了。 segue 工作似乎没有继承从 FeedsViewTableController 传递到函数 AddNewFeed 的数据。 您需要添加我在回答 FeedsTableViewController 时发布的方法并删除您的 prepareForSegue。将情节提要中 AddFeedViewController 中的关闭按钮连接到“退出”segue。

以上是关于Swift segue 不会将数据传递给旧的 ViewController的主要内容,如果未能解决你的问题,请参考以下文章

通过 Segue 将数据传递给新的 ViewController

将数据传递给父场景的委托与展开 Segue

在准备 segue 时,如何将数据传递给子 UIViewController?

在函数内将数据传递给 segue.destination 的问题

使用 Storyboard Segue iOS 将数据传递给视图控制器

使用 performSegue 将数据传递给目标视图控制器