【问题标题】:PrepareForSegue from a UIButton in a custom prototype cell来自自定义原型单元中的 UIButton 的 PrepareForSegue
【发布时间】:2015-09-01 22:07:42
【问题描述】:

正如标题所说,我有一个带有原型单元格的 tableView;单元格是一个自定义单元格(所以我创建了一个名为CustomCell.swift 的类,我为图像、标签、按钮等创建了IBOutlet);这是我的课

import UIKit

class CustomCell: UITableViewCell
{
    @IBOutlet var imageSquadra: UIImageView!
    @IBOutlet var button: UIButton!

    override func awakeFromNib()
    {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool)
    {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

然后我做了UITableViewController:

import UIKit

class SquadreController: UITableViewController
{
    var index: NSIndexPath?
    var isScrolling = Bool()

    override func viewDidLoad()
    {
        super.viewDidLoad()

        DataManager.sharedInstance.createCori()

    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
    }

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return DataManager.sharedInstance.arrayCori.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
        let squadra = DataManager.sharedInstance.arrayCori[indexPath.row]

        cell.backgroundColor = UIColor.clearColor()

        if (indexPath.row % 2 == 0)
        {
            cell.backgroundColor = UIColor.greenColor()
        }
        else
        {
            cell.backgroundColor = UIColor.blueColor()
        }

        //Here I added target to the button in the cell, and below in the class I implemented the fun makeSegue()
        cell.button.addTarget(self, action: "makeSegue", forControlEvents: UIControlEvents.TouchUpInside)

        return cell
    }


    //Following 4 method are used to detect UIScollView scrolling and to change cell height.
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        index = indexPath
        tableView.beginUpdates()
        tableView.endUpdates()
    }

    override func scrollViewWillBeginDragging(scrollView: UIScrollView)
    {
        isScrolling = true
        tableView.beginUpdates()
        tableView.endUpdates()
    }

    override func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
    {
        isScrolling = false
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
    {
        if isScrolling
        {
            return 100
        }

        if index == indexPath
        {
            return 200
        }
        else
        {
            return 100
        }
    }

    //Here I implemented the makeSegue() func, the action I had made as target of the button.
    func makeSegue() {
        self.performSegueWithIdentifier("toCoriViewController", sender: self)
    }
}

好的,现在最困难的部分来了:制作prepareForSegue;我没有任何想法如何解决这个问题,我试过了

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    {
        if segue.identifier == "toCoriViewController"
        {
            if let indexPath = ?????????????
            {
                let controller = segue.destinationViewController as! CoriViewController
                controller.coriSquadra = DataManager.sharedInstance.arrayCori[indexPath.row]
            }
        }
    }

但我不知道如何设置常量indexPath。

哦,首先我通过控制权从按钮到第二个控制器进行了转场:也许我必须从 tableView 单元格进行转场???

希望有人可以帮助我!

【问题讨论】:

    标签: swift uitableview uibutton uistoryboardsegue custom-cell


    【解决方案1】:

    你可以像这样得到单元格的索引路径

    let indexPath : NSIndexPath
    if let button = sender as? UIButton {
        let cell = button.superview?.superview as! UITableViewCell
        indexPath = self.tableView.indexPathForCell(cell)
    }
    

    您还需要像这样更改您的makeSegue:

    func makeSegue(button:UIButton) {
        self.performSegueWithIdentifier("toCoriViewController", sender: button)
    }
    

    在您的cellForRowAtIndexPath 中,只需将您设置操作的行更改为cell.button.addTarget(self, action: "makeSegue:", forControlEvents: UIControlEvents.TouchUpInside)。

    或者,您可以在自定义单元格类中创建一个squadra 属性来保存该单元格的arrayCori 值,因此您将拥有一些如下所示的代码:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell
        let squadra = DataManager.sharedInstance.arrayCori[indexPath.row]
        cell.squadra = squadra #add this line
        cell.backgroundColor = UIColor.clearColor()
        if (indexPath.row % 2 == 0)
        {
            cell.backgroundColor = UIColor.greenColor()
        }
        else
        {
            cell.backgroundColor = UIColor.blueColor()
        }
    
        //Here I added target to the button in the cell, and below in the class I implemented the fun makeSegue()
        cell.button.addTarget(self, action: "makeSegue", forControlEvents: UIControlEvents.TouchUpInside)
    
        return cell
    }
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
    {
        if segue.identifier == "toCoriViewController"
        {
            let controller = segue.destinationViewController as! CoriViewController
            if let button = sender as? UIButton {
                let cell = button.superview?.superview as! CustomCell
                controller.coriSquadra = cell.squadra
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答!但是当我运行项目并在按钮内部进行触摸时,Xcode 给了我这个错误“无法将'UIButton'(0x10d693f68)类型的值转换为'UITableViewCell'(0x10d6939f0)”。如果我将控制权从单元格转到第二个控制器,Xcode 会给我另一个错误“Could not cast value of type 'Cori_da_stadio.SquadreController' (0x1084610e0) to 'UITableViewCell' (0x10ab8a9f0).”
    • 哦,那是我的错,忘记了发件人的按钮而不是单元格。只需致电sender.superview 即可获取该单元格。将编辑
    • 所以你必须添加另一个.superview,或者可能是一对——我不知道你的单元格是如何布局的,所以我不能告诉你需要多少次调用它,但只需继续添加它们直到它起作用。喜欢:let cell = sender.superview?.superview as! UITableViewCell
    • 如果我添加两次 .superview Xcode 建议我将代码更改为 let cell = sender!.superview!!.superview as! CustomCell 否则它不会编译,如果我这样做,Xcode 会告诉我“在展开可选值时发现 nil”
    • 如果您尝试获取单元格的 indexPath,请将UITableViewCell 放在as 之后,但如果您使用属性进行操作,则将CustomCell 放在as 之后。如果你做sender.superview?.superview as! CustomCell,它应该让你。我发现如果你只是删除所有的“!”和“?”,然后让 xcode 重新添加它们,它以正确的方式添加它们,否则它就像现在为你做的那样。 (抱歉造成混淆)
    【解决方案2】:

    故事板 + prepareForSegue

    只需添加一个单独的UIStoryboardSegue 并为故事板中的按钮添加一个单独的标识符,几乎无需代码即可完成。

    prepareForSegue 变为:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if "fromButtonToViewController" == segue.identifier {
            if let button = sender as? UIButton {
                // ... The UIButton is the sender
            }
        }
    }
    

    这会同时或单独处理点击单元格和点击按钮,将正确的sender 传递给prepare:segue:sender,从而允许自定义单元格、按钮、转换以及最终的目标视图。该语句的演示可以在下面的紧凑项目中找到。


    ► 在GitHub 上查找此解决方案,在Swift Recipes 上查找更多详细信息。

    【讨论】:

      【解决方案3】:

      对于那些正在寻找通用方法的人。

      /* Generic function to get uitableviewcell from any UIKit controllers which stored in deep level of views or stackviews */
      
      func getCell<T>(_ view: T) -> UITableViewCell? {
      
          guard let view = view as? UIView else {
              return nil
          }
      
          return view as? UITableViewCell ?? getCell(view.superview)
      }
      
      
      override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
      {
          if segue.identifier == "toCoriViewController"
          {
              if let button = sender as? UIButton,
                  let cell = getCell(button),
                  let indexPath = tableView.indexPath(for: cell)
              {
                  let controller = segue.destinationViewController as! CoriViewController
                  controller.coriSquadra = DataManager.sharedInstance.arrayCori[indexPath.row]
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-17
        • 1970-01-01
        • 1970-01-01
        • 2012-08-12
        • 2014-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多