【问题标题】:How to push a new view controller when a table cell is tapped?点击表格单元格时如何推送新的视图控制器?
【发布时间】:2015-08-14 15:49:45
【问题描述】:

我创建了这个包含 3 个部分和 7 行的表。代码如下所示

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet var subjectTabelView: UITableView!

var slSubject = ["English Lang&Lit", "Chinese Lang&Lit", "Economics"]
var hlSubject = ["Mathematics", "Chemistry", "Biology"]
var tokSubject = ["Theory of Knowledge"]

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    subjectTabelView.dataSource = self
    subjectTabelView.delegate = self
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 3
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0{
        return hlSubject.count
    }else if section == 1{
        return slSubject.count
    }else {
        return tokSubject.count
    }

}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let subjectCell = tableView.dequeueReusableCellWithIdentifier("idSubjectCell", forIndexPath: indexPath) as! UITableViewCell

    if indexPath.section == 0 {
        subjectCell.textLabel?.text = hlSubject[indexPath.row]
    } else if indexPath.section == 1{
        subjectCell.textLabel?.text = slSubject[indexPath.row]
    } else {
        subjectCell.textLabel?.text = tokSubject[indexPath.row]
    }

    return subjectCell
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if section == 0 {
        return "HL"
    } else if section == 1{
        return "SL"
    } else {
        return "ToK"
    }
}



}

我必须做什么才能使该表中的每个单元格在被点击时推送一个新的视图控制器?我的故事板图片如下所示。在我的故事板中,我的视图控制器中,我已经创建了一个导航控制器,并将具有表的视图控制器设置为 rootViewController。目前,我的 tableView 只有一个原型单元格和一个单元格标识符。

谢谢!

【问题讨论】:

  • 您的故事板图片未显示。
  • @HugoAlonso 嗨,抱歉,stackOverflow 不允许我发布图片,因为我的声誉不够高

标签: ios swift uitableview navigationcontroller


【解决方案1】:

假设您的“locationVC”是:

class LocationVC: UIViewController {

    @IBOutlet weak var fromWhereLabel: UILabel!
    //This can be changed when creating this UIViewController
    var textToShow : String?

    override func viewWillAppear(animated: Bool) {
        if let textToShow = textToShow {
            fromWhereLabel.text = textToShow
        }
    }
}

然后,只需在名为UIViewControllerViewController 中的代码中添加以下函数(应该有一个更好的名称;-))你可以实现你的目标。

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
      //if such cell exists and destination controller (the one to show) exists too..
        if let subjectCell = tableView.cellForRowAtIndexPath(indexPath), let destinationViewController = navigationController?.storyboard?.instantiateViewControllerWithIdentifier("locationVC") as? LocationVC{
            //This is a bonus, I will be showing at destionation controller the same text of the cell from where it comes...
            if let text = subjectCell.textLabel?.text {
                destinationViewController.textToShow = text
            } else {
                destinationViewController.textToShow = "Tapped Cell's textLabel is empty"
            }
          //Then just push the controller into the view hierarchy
          navigationController?.pushViewController(destinationViewController, animated: true)
        }
     }

您将能够在每次点击单元格时启动一个LocationVC UIViewController,它具有一定的价值来证明它是正确的。 :)

希望对你有帮助!

更新: 下面的代码和说明用于允许启动 点击单元格

后不同的UIViewControllers

1.- 让我们创建一个类,它将成为每个新 UIViewControllers 的父类(我们愿意从 tableview 单元格的水龙头中删除):

public class CommonDataViewController: UIViewController {
//Here we are going to be putting any data we want to share with this view
  var data: AnyObject?
}

2.- 让我们创建一些导航规则,以便进行组织 ;-)

enum Navigation: Int {
    case vc1 = 0, vc2 = 1, vc3 = 2, vc4 = 3
    //How many rules we have (for not to exceed this number)
    static let definedNavigations = 4
    //This must return the identifier for this view on the Storyboard
    func storyboardIdentifier() -> String {
        //for this example's sake, we have a common prefix for every new view controller, if it's not the case, you can use a switch(self) here
        return "locationVC_\(self.rawValue + 1)"
    }
}

现在,让我们以之前的代码为基础:

3.- 为清楚起见,让我们对之前的 LocationVC 稍作改动(在本例中,将有一个 Storyboard Identifier 和文本 "locationVC_1"

class LocationVC: CommonDataViewController {

    @IBOutlet weak var fromWhereLabel: UILabel!

    //This is optional, but improves clarity..here we take our AnyObject? variable data and transforms it into the type of data this view is excepting 
    var thisVCReceivedData: String? {
        return data as? String
    }

    override func viewWillAppear(animated: Bool) {
        if let textToShow = thisVCReceivedData {
            fromWhereLabel.text = textToShow
        }
    }
}

4.- 现在,我们在 didSelectRowAtIndexPath 函数中触发所有这些。

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    //Just to avoid tapping on a cell that doesn't have an UIViewController asociated
    if Navigation.definedNavigations > indexPath.row {
        //The view's instance on our Navigation enum to which we most go after tapping this cell
        let nextView = Navigation(rawValue: indexPath.row)!
        //The identifier of the destination CommonDataViewController's son in our Storyboard
        let identifier = nextView.storyboardIdentifier()
        //If everything exists...
        if let subjectCell = tableView.cellForRowAtIndexPath(indexPath), let destinationViewController = navigationController?.storyboard?.instantiateViewControllerWithIdentifier(identifier) as? CommonDataViewController {

            //here you can use a switch around "nextView" for passing different data to every View Controller..for this example, we just pass same String to everyone
            if let text = subjectCell.textLabel?.text {
                destinationViewController.data = text
            } else {
                destinationViewController.data = "Tapped Cell's textLabel is empty"
            }
            navigationController?.pushViewController(destinationViewController, animated: true)
        }
    }
}

请注意,您可以使用协议和委托方法获得相同的结果,这更容易解释

【讨论】:

  • 嗨!我有一个问题,这会显示 viewController 中单元格的内容吗?例如在 twitter 上,当你点击一条推文时,它会在不同的 viewController 中打开这条推文,但只显示这条推文并允许你对其发表评论。
  • @HugoAlonso,我要创建一个新文件 LocationVCViewController.swift 吗?这个解决方案是否允许我为我的 7 个不同的单元创建 7 个不同的视图控制器?谢谢
  • @BrunoRecillas 是的,你可以用这种方法做类似的事情,你只需传递你的推文、数据等的实例,而不仅仅是 .textToShow 中的文本,你就可以开始了。
  • @ShawnClarke 现在,很高兴提前知道,抱歉没有早点发现 ;-) (只是为了让您知道,即使您无法发布图片,您也可以链接给他们)..所以,回答你的问题:仅仅创建一个LocationVCViewControllerLocationVC 是不够的。就此而言,请澄清一下:您提前知道,对于您要显示的每个新 ViewController,哪一行 (indexPath.row) 将就位? 换句话说,您的单元格始终位于一样的地方? ..ex:导致 newVC_3 的总是在第 3 行,newVC_2 在第 2 行,等等。?
  • 您能说得更具体一点吗?请? @雨果阿隆索
【解决方案2】:

要在 UINavigationController 中推送视图控制器,您只需使用以下代码:

ViewController *viewController = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"locationVC"];
[self.navigationController pushViewController:viewController animated:YES];

你要找的方法是这个:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    ViewController *viewController = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:@"locationVC"];
    [self.navigationController pushViewController:viewController animated:YES];
}

【讨论】:

  • 这段代码在Objective-C中,问题是如何在swift中实现这一点
  • @Hugo 在他的问题中说他已经创建了一个导航控制器。
  • @MSU_Bulldog 嗨,谢谢你的建议,但是如果我想让不同的单元格推送不同的视图怎么办,这意味着会有更多的多个标识符?谢谢
  • 我想要对应用程序做的是,我希望所有科目都有一个不同的视图控制器,并且应用程序将允许用户输入每个科目的成绩,应用程序将绘制图表键入的值。
【解决方案3】:

您可以使用 prepareForSegue 方法。您只需要设置目标视图。或 didselectrowatindexpath prepareForSegue 代码如下:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "nameofTheSegue"
{
    if let destinationVC = segue.destinationViewController as? OtherViewController{
        // do whatever you want with the data you want to pass.
    }
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    相关资源
    最近更新 更多