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的主要内容,如果未能解决你的问题,请参考以下文章