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 时,如何将数据传递给子 UIViewController?
在函数内将数据传递给 segue.destination 的问题