通过 segue 在视图控制器之间传递数据
Posted
技术标签:
【中文标题】通过 segue 在视图控制器之间传递数据【英文标题】:Passing data between view controllers through segue 【发布时间】:2016-11-21 12:35:49 【问题描述】:我有一个MapViewController
和一个prepareForSegue(_:sender:)
方法,我打算用它来向LandmarkTableViewController
发送数据,并在按下按钮时调用。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
let destinationvc = segue.destinationViewController
if let landmarkvc = destinationvc as? LandmarkTableViewController
if let identifier = segue.identifier
let library = Landmark(name: "Run Run Shaw Library", properties: ["Chinese Kanji", "Gray", "Green Plants"])
let bank = Landmark(name: "Hang Seng Bank", properties: ["Chinese Kanji", "Green"])
switch identifier
case "showLibrary" : landmarkvc.passedLandmark = library // pass data to LandmarkTableViewController
case "showBank" : landmarkvc.passedLandmark = bank // pass data to LandmarkTableViewController
default : break
LandmarkTableViewController
已正确设置为显示字符串数组properties
,每行有一个字符串。所以我打算做的是根据按下哪个按钮将表格的相应数据传递给properties
,并让LandmarkTableViewController
显示对应的properties
。
class LandmarkTableViewController: UITableViewController
var properties = [String]()
var passedLandmark = Landmark(name: "temp", properties: ["temp"]) // initially set to default value
override func viewDidLoad()
super.viewDidLoad()
loadSampleProperties()
func loadSampleProperties()
self.properties = passedLandmark!.properties
// other methods....
class Landmark
var name: String
var properties: [String]
init?(name: String, properties: [String])
self.name = name
self.properties = properties
// Initialization should fail if there is no name or if there is no property.
if name.isEmpty || properties.isEmpty
return nil
但是,当我运行代码时,表格视图中只显示 temp。 我已经坚持了很长时间,所以非常感谢任何帮助!
编辑: viewDidLoad() 中的 loadData() 更改为正确的 loadSampleProperties()。我在将代码发布到问题时出错。
【问题讨论】:
您确定您的目标视图控制器是LandmarkTableViewController
(它可能是根视图控制器为LandmarkTableViewController
的导航控制器)?您的 segue 是否设置了“showLibrary”和“showBank”标识符?另外,您在某处打电话给loadSampleProperties()
吗?设置属性后是否重新加载表数据?
@albertamg 我刚刚注意到你指出的:LandmarkTableViewController
的目标视图控制器确实是一个导航控制器,其根视图控制器是 LandmarkTableViewController
。你知道我是怎么解决这个问题的吗?因为我仍然没有任何想法。
然后在prepareForSegue()
中访问您的LandmarkTableViewController
,如下所示:if let navController = segue.destinationViewController as? UINavigationController, let landmarkVC = navController.viewControllers[0] as? LandmarkTableViewController //...
【参考方案1】:
如果不仔细检查您的标识符,我认为这应该可以解决您的问题 并且您可以通过将 print(passedLandmark) 添加到 viewDidLoad() 或断点来确保数据传递,以确保您获取数据
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
let destinationvc = segue.destinationViewController
if let landmarkvc = destinationvc as? LandmarkTableViewController
if segue.identifier == "showLibrary"
let library = Landmark(name: "Run Run Shaw Library", properties: ["Chinese Kanji", "Gray", "Green Plants"])
landmarkvc.passedLandmark = library
if segue.identifier == "showBank"
let bank = Landmark(name: "Hang Seng Bank", properties: ["Chinese Kanji", "Green"])
landmarkvc.passedLandmark = bank
希望这会有所帮助
【讨论】:
【参考方案2】:您的报价中缺少代码,所以我不能确定,但我假设您的 loadData() 方法是使用您在 prepareForSegue 中传递的 Landmark 重新加载表视图数据的方法。如果是这样的话:
viewDidLoad() 被调用before prepareForSegue,这样destinationViewController 的所有视图和元素都被加载并准备好使用。因此,在您的情况下,表格视图会加载您的“临时”数据,并且在您设置正确的数据时不会重新加载。
您有两个选择: 例如,您可以在 viewWillAppear 中调用 loadData()/reloadData(),它在 prepareForSegue() 之后调用。请记住, viewWillAppear 可能会在其他导航中再次调用。 否则,您可以在父视图控制器中实例化并呈现/推送新控制器,而不是使用 segue。
【讨论】:
以上是关于通过 segue 在视图控制器之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章
如何在视图控制器之间传递数据而不在 ios 中使用 segue?
在视图控制器之间传递 iOS 10 Segue 中的数据 [重复]
在视图控制器之间传递数据 - Storyboards segues