我在这里要做的是当我在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的子类,你已经分别声明和连接了两个IBOutlet,比如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中即可为您提供“后退”按钮功能.在Storyboard中选择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类在你或它周围传递之前(即到
当你从中查看tableView单元格时,UI元素,闭包,另一个VC等)
MyTableViewController场景将转移到您的下一个ViewController
场景(即你的myViewController场景),iOS尚未实例化
那个第二个场景呢.所以你需要一个属性来保存数据
你试图首先传递到你的第二个场景View Controller,你可以
稍后在该类最终加载时使用它.
所以你的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中标签和约定的注意事项:
>开始用大写字母命名类(即类
ViewController(){})
>类和属性应该捕获它们的含义
代表.我建议你改变你的MyTableViewController
和’myViewController’相应地反映了他们真实的东西
意思是或做(你可以使用’MainTableViewController’和’DetailViewController’.这样做会很好).
>使用camelToe标签来表示属性和方法. (我用过你的标签
在你的问题中提供,以免过多地混淆你).
请享用!