按下 CollectionViewCell 内的按钮后如何呈现 ViewController

Posted

技术标签:

【中文标题】按下 CollectionViewCell 内的按钮后如何呈现 ViewController【英文标题】:How to present a ViewController after pressing a button inside of a CollectionViewCell 【发布时间】:2017-10-19 11:11:05 【问题描述】:

嘿,我是编程新手,我的问题是,我有一个UICollectionViewController,其中有 4 个可水平滚动的单元格。在第 4 个单元格内,我在 UIView (ProfileContainerView) 顶部有一个 UIButton(optionsButton)。

我要呈现的UIViewControllerProfileEditViewController,设置在Main.storyboard

按此按钮后如何显示UIViewController

ProfileCell:

class ProfileCell: UICollectionViewCell 

    let profileContainerView: UIView = 
        let view = UIView()
        return view
    ()

    lazy var optionsButton: UIButton = 
        let btn = UIButton(type: .custom)
        btn.setImage(#imageLiteral(resourceName: "Settings"), for: UIControlState.normal)
        btn.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
        return btn
    ()

    @objc func handleOptionsButton() 
        print("Button pressed")
    

HomeViewController:

class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout 


    let profileCelId = "profileCell"

    override func viewDidLoad() 
        super.viewDidLoad()
        setupSwipeView()
    


    func setupSwipeView() 
        collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)
        collectionView?.register(ProfileCell.self, forCellWithReuseIdentifier: profileCelId)        
    


    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell         
        if indexPath.item == 3 
            return collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
        
        return cell
    

【问题讨论】:

检查这个:***.com/questions/43766963/… 【参考方案1】:

您可以使用委托来实现这一点。

下面是实现这个的代码

 protocol ProfileCollectionViewCellDelegate 
 func buttonPressedAtIndexPath(inCell: ProfileCell)
 

class ProfileCell: UICollectionViewCell 

var delegate : ProfileCollectionViewCellDelegate?
let profileContainerView: UIView = 
    let view = UIView()
    return view
()

lazy var optionsButton: UIButton = 
    let btn = UIButton(type: .custom)
    btn.setImage(#imageLiteral(resourceName: "Settings"), for: UIControlState.normal)
    btn.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
    return btn
()

@objc func handleOptionsButton() 
    if self.delegate != nil 
        self.delegate?.buttonPressedAtIndexPath(self)
    


对于您的 HomeViewController

 class HomeViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, ProfileCollectionViewCellDelegate  


let profileCelId = "profileCell"

override func viewDidLoad() 
    super.viewDidLoad()
    setupSwipeView()



func setupSwipeView() 
    collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cell)
    collectionView?.register(ProfileCell.self, forCellWithReuseIdentifier: profileCelId)        



  override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell         

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
    cell.delegate = self
    return cell
 

fun buttonPressedAtIndexPath(inCell: ProfileCell) 
       let indexOfCell = self.collectionView.indexPath(for: cell)
        if indexOfCell.row == 3 
            //Do your work here
        




【讨论】:

谢谢你的回答我会试试的 弗兰克你试过了吗? 对不起,我没有注意到你给我写信 是的,我试过了。但不幸的是,它对我不起作用。但无论如何感谢您的回答和时间! 出了什么问题?【参考方案2】:

您可以通过以下方式展示您的ProfileEditViewController,其样式在您的Main.storyboard 中:

1) 给你的ProfileEditViewController 一个StoryBoard ID。例如。 “ProfileEditViewController” - 关于这个的一些问题在这里:What is a StoryBoard ID and how can i use this?

2) 为UIButton 上的操作注册UIViewController 或提供适当的回调功能。 由于您的 HomeViewController 也是您的 Collection View 的数据源,您可以轻松扩展您的 DataSource 方法

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell`

实现可能如下所示:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell         
    if indexPath.item == 3 
        let profileCell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
        if let _cell = cell as? ProfileCell,
           let button = _cell.optionsButton as? UIButton 
            button.addTarget(self, action: #selector(handleOptionsButton), forControlEvents: UIControlEvents.TouchUpInside)
        
        return profileCell;
    
    return cell

确保您的按钮操作现在也由您的HomeViewController 实现

@objc func handleOptionsButton() 
    print("Button pressed")

3) 现在在HomeViewController.handleOptionsButton 中,您需要提供一种功能来支持转换到具有所需 StoryboardID 的特定控制器:

let storyboard = UIStoryboard(name: "Main", bundle:Bundle.main)
let controller = storyboard.instantiateViewController(withIdentifier: "ProfileEditViewController")
self.present(controller, animated: true, completion: nil)

【讨论】:

我试过了,但它显示'ProfileCell'类型的值没有成员'present' present 是由UIViewControllers 实现的功能,请参见此处:developer.apple.com/documentation/uikit/uiviewcontroller/…。例如,您可以为 Uibutton 的操作注册 UIViewController。我会调整我的答案。 好的,我会试试这个,让你知道它是否有效。感谢您的宝贵时间 if let button = profileCell.optionsButton as? UIButton button.addTarget(self, action: #selector(handleOptionsButton), forControlEvents: UIControlEvents.TouchUpInside) 哦,是的,我明白了,我学到了很多,谢谢。如果你想看看我做了什么,我添加了评论。【参考方案3】:

让 proCell = ProfileCell()

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cell, for: indexPath)
    if indexPath.item == 3 
        let profileCell = collectionView.dequeueReusableCell(withReuseIdentifier: profileCelId, for: indexPath)
        let button = proCell.optionsButton
            button.addTarget(self, action: #selector(handleOptionsButton), for: UIControlEvents.touchUpInside)
        return profileCell;
    
    return cell

【讨论】:

以上是关于按下 CollectionViewCell 内的按钮后如何呈现 ViewController的主要内容,如果未能解决你的问题,请参考以下文章

自定义 CollectionViewCell 处理按钮按下

单击 CollectionViewCell 内的 ImageView 以转到 ViewController

在 CollectionViewCell 内的 ScrollView 内缩放 UIImage [重复]

如何为 collectionviewcell 内的进度条创建 IBOutlet?

约束 UIView 内的标签,该标签位于可扩展 collectionViewCell 内

uiCollectionViewCell 内的 Uitableview