[英]Passing data between View Controllers in Swift (From TableView to DetailViewController)
我有两个文件,MyTableViewController和myViewController。 我在MyTableVIewController中的TableCell上设置了UIImageView。 myViewController不包含任何内容。 我创建了一个名为ImageArray的数组,其中包含一个Images数组。
我在这里要做的是当我在myTableViewController中单击TableCell上的图像时,我希望单击的图像出现在myViewController中。 还有关于图像旁边点击图像的一些描述。 我想使用myViewController让用户获取所选图像的详细信息。
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell
var ImageView = cell.viewWithTag(1) as! UIImageView
ImageView.image = UIImage(named: ImageArray[indexPath.row])
ImageView.contentMode = .ScaleAspectFit
var TextView = cell.viewWithTag(2) as! UILabel
TextView.text = ImageArray[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("next", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "next") {
let destination = segue.destinationViewController as! myViewController
}
}
我不知道如何做到这一点。 如果你能帮助我搞清楚,我真的很感激! 谢谢!
首先,我假设您的MyTableViewController类符合UITableViewDataSource和UITableViewDelegate协议,并且您已将MyTableViewController类设置为代码或通过Storyboard的委托。
经过整理,有多种方法可以实现您所寻求的结果。 您可以在一个独立的类中声明ImageArray并在MyTableViewController类中调用它,使用tableView委托方法将它们索引到tableView上,最后使用prepareForSegue方法将图像推送到myViewController上。 或者您可以在MyTableViewController类的顶部简单地声明和初始化ImageArray,如下所示:
var ImageArray = [("Moscow Russia.jpg", "Europe"),
("London England.jpg", "Europe")]
在上面的ImageArray中 ,确保您的图像名称与您导入Xcode项目的资产名称完全匹配。
然后我们使用下面所需的方法指定我们需要ImageArray在tableView上占用的部分行数(即基本上将我们的ImageArray计入我们的TableView):
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return ImageArray.count ?? 0
}
接下来,您希望使用tableView:cellForRowAtIndexPath:方法在单元格的每一行中显示ImageArray 。
您的TableCell侧面说明:希望您的TableCell的是从子类的UITableViewCell,并且您已经申报并分别连接的两个IBOutlets,也就是说,imageview的并且为textLabel。 此外,确保您的TableCell正确地链接到Identity Inspector下的Storyboard中的原型单元格。您的TableCell类应如下所示:
import UIKit
class CustomTableViewCell: UITableViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var textLabel: UILabel!
}
现在回到MyTableVIewController类。 从你的代码中,我看到你正在将'let cell = ...'作为'UITableViewCell'。 您应该将其转换为“TableCell”,因为您正在对其进行子类化。 实现tableView:cellForRowAtIndexPath:方法如下:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! TableCell
//Note that I'm using tuples here. Pretty cool huh. Got to love Swift!
let (imageName, textNameToGoWithImage) = ImageArray[indexPath.row]
cell.textLabel.text = textNameToGoWithImage
cell.imageView.image = UIImage(named: imageName)
cell.imageView.contentMode = .ScaleAspectFit
// You could have also used 'if let' in optional binding to safely unwrap your image if you want like below.
// if let image = UIImage(named: imageName){
// cell.imageView?.image = image
// cell.imageView.contentMode = .ScaleAspectFit
// }
return cell
}
看起来你对使用performSegueWithIdentifier方法的时间和地点感到有点困惑,而不是使用 - prepareForSegue方法。 甚至何时使用tableView:didSelectRowAtIndexPath方法 。
我在这里简单解释一下。 当您没有控制时,可以使用performSegueWithIdentifier方法 - 将一个ViewController的场景中的segue拖动到Storyboard中的另一个场景。 这样,只要您在“ 属性检查器 ”下的“故事板”中指定了正确的标识符,使用performSegueWithIdentifier方法就可以在ViewController场景之间移动。 “
现在,如果您使用的是Storyboard,则不需要tableView:didSelectRowAtIndexPath方法。 tableView:didSelectRowAtIndexPath方法的作用是告诉委托现在选择了指定的行,我们可以在其代码体内执行某些操作(例如将图像或文本推送到另一个ViewController场景,就像您尝试做的那样)。 但是当你使用segues时,这就变得多余了。 您所要做的就是控制 - 将您的MyTableViewController场景中的表格单元格中的segue 拖动到myViewController场景。 选择“ 显示 ”并为segue指定一个标识符名称,就像你“ 下一步 ”一样。 ( 小边注:如果你想后退按钮的功能,在顶部导航栏,当你运行你的应用程序中显示,只需嵌入您MyTableViewController在一个UINavigationController给你,“ 后退 ”按钮功能与您的MyTableViewController场景在故事板中选择。 ,转到顶部菜单,然后选择编辑>>嵌入>>导航控制器 。然后walla !!)
现在让我们继续实现我们的tableView:prepareForSegue方法,如下所示:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "next" {
//Note that, originally, destinationViewController is of Type UIViewController and has to be casted as myViewController instead since that's the ViewController we trying to go to.
let destinationVC = segue.destinationViewController as! myViewController
if let indexPath = self.tableView.indexPathForSelectedRow{
let selectedRow = ImageArray[indexPath.row]
destinationVC.imageName2 = selectedRow.0
destinationVC.textName2 = selectedRow.1
}
从上面的代码中,确保首先在myViewController类中将' imageName '和' textName '设置为属性 ,然后才能使用' destinationVC '访问它们,而' destinationVC现在是myViewController类型。 这两个属性将保存我们从MyTableViewController类传递到myViewController类的数据。 我们正在使用数组索引相应地将数据传递给这两个属性。
然后,您可以通过将这些设置' imageName2 '和' textName2 '属性传递到您的出口(或任何UI控件)来创建两个IBOutlet来显示您的图像和文本。
所以你的myViewController类应该如下所示:
import UIKit
class myViewController : UIViewController {
//Your two strings to initially hold onto the data
//being passed to myViewController class
var imageName2 : String?
var textName2 : String?
@IBOutlet weak var detailImageView: UIImageView!
@IBOutlet weak var detailTextNameLabel: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
detailTextNameLabel.text = textName2!
if let image = UIImage(named: imageName2!) {
self.detailImageView.image = image
}
}
就是这样!
关于Swift中标签和约定的注意事项:
使用camelToe标签来表示属性和方法。 (我使用了你在问题中提供的标签,以免过多地混淆你)。
请享用!
这应该有助于:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "next") {
let destination = segue.destinationViewController as! myViewController
destination.imageView.image = UIImage(named: ImageArray[tableView.indexPathForSelectedRow?.row])
destination.textView.text = ImageArray[tableView.indexPathForSelectedRow?.row]
}
}
(imageView和textView是新viewController中的视图。)
注意:
tableView.indexPathForSelectedRow?.row
应该给你所选择的行,顾名思义,但它可以是nil
,所以要小心。 imageView
是正确的方法,而ImageView
是不正确的。 在swift 3中,您可以执行以下操作:
在MyTableViewController
类中:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! UITableViewCell
// for imageview
var ImageView : UIImageView = cell.contentView.viewWithTag(1) as! UIImageView
ImageView.image = UIImage(named: ImageArray[indexPath.row])
// for text
var TextView : UILabel = cell.contentView.viewWithTag(2) as! UILabel
ImageView.text = ImageArray[indexPath.row]
return cell
}
在你的didSelectRow
方法中:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "myViewController") as! myViewController
nextVC.myImgView.image = UIImame(named: ImageArray[indexPath.row])
nextVC.myLabel.text = ImageArray[indexPath.row]
self.present(nextVC!, animated: true)
}
在myViewController
类中:
class myViewController: UIViewController
{
let myImageView = UIImageView()
let myLabel = UILabel()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.