从 UICollectionViewCell 调用函数以在 UICollectionView 中使用
Posted
技术标签:
【中文标题】从 UICollectionViewCell 调用函数以在 UICollectionView 中使用【英文标题】:Call function from UICollectionViewCell to use in UICollectionView 【发布时间】:2018-02-16 16:49:23 【问题描述】:我有一个 UICollectionViewCell,它创建一堆文本字段和一个函数 (handleNewJob),它查看在单元格中创建的所有文本字段并将它们写入 firebase。
但是,我想要的是我在 UICollectionView 中创建的按钮从 UICollectionViewCell 调用函数 (handleNewJob)。
这可能吗?我尝试在 UICollectionView 中使用该函数,但似乎无法引用所有 textfields.text?
这是我在 UICollectionViewCell 中的函数(我没有包含所有文本字段生成,因为它很长):
// HANDLE NEW JOB
func handleNewJob()
let newJobBrand = jobBrand.text!
let newJobName = jobName.text!
let newDirectorName = directorName.text!
let newAgencyName = agencyName.text!
let newProdCoName = prodCoName.text!
// WHERE TO PUT IN DATABASE
let reference = Database.database().reference().child("jobInfo")
let childRef = reference.childByAutoId()
// REFERENCING DICTIONARY
let jobBrandValue = ["jobBrand": newJobBrand]
let jobNameValue = ["jobName": newJobName]
let jobDirectorValue = ["directorName": newDirectorName]
let jobAgencyNameValue = ["agencyName": newAgencyName]
let jobProdCoValue = ["prodCoName": newProdCoName]
// WRITE TO DATABASE
childRef.updateChildValues(jobBrandValue)
childRef.updateChildValues(jobNameValue)
childRef.updateChildValues(jobDirectorValue)
childRef.updateChildValues(jobAgencyNameValue)
childRef.updateChildValues(jobProdCoValue)
这是我的 UICollectionView 代码 - 我想调用 handleNext 按钮下的函数:
import UIKit
import Firebase
class page_newJobSwipingController : UICollectionViewController, UICollectionViewDelegateFlowLayout, UIImagePickerControllerDelegate, UINavigationControllerDelegate
// VARIABLES
var ref:DatabaseReference?
// BOTTOM BUTTONS
private let previousButton: UIButton =
let button = UIButton(type: .system)
button.setTitle("Previous", for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
button.setTitleColor(.gray, for: .normal)
button.addTarget(self, action: #selector(handlePrev), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
()
private let nextButton: UIButton =
let button = UIButton(type: .system)
button.setTitle("Next", for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
let pinkColour = UIColor(red: 232/255, green: 68/266, blue: 133/255, alpha: 1)
button.setTitleColor(.mainPink, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(handleNext), for: .touchUpInside)
return button
()
// SET UP NEXT AND PREVIOUS BUTTONS TO HAVE A FUNCTION
@IBAction func handlePrev(sender : UIButton)
let prevIndex = max(pageControl.currentPage - 1, 0)
pageControl.currentPage = prevIndex
let indexPath = IndexPath(item: prevIndex, section: 0)
collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
@IBAction func handleNext(sender : UIButton)
let nextIndex = pageControl.currentPage + 1
pageControl.currentPage = nextIndex
if nextIndex == 1
print ("move to page 2")
else
print ("send alert message")
newJobCellGeneral.handleNewJob()
storyboardAlert()
let indexPath = IndexPath(item: 1, section: 0)
collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
// HANDLE UPLOAD STORYBOARD OPTIONS
@IBAction func storyboardAlert()
let imagePickerController = UIImagePickerController()
imagePickerController.delegate = self
// ACTION SHEET FOR ADDING NEW ATTACHMENT
let alert = UIAlertController(title: "Job Created", message: "Do you want to upload storyboard cells now?", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Now", style: .default, handler: (action:UIAlertAction) in
let storyboardUpload = page_newJobStoryboardUpload()
self.show(storyboardUpload, sender: self)
))
alert.addAction(UIAlertAction(title: "Later", style: .default, handler: (action:UIAlertAction) in
let jobList = page_jobList()
self.show(jobList, sender: self)
))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
// PAGE CONTROL
private let pageControl: UIPageControl =
let pc = UIPageControl()
pc.numberOfPages = 2
pc.currentPageIndicatorTintColor = .mainPink
pc.pageIndicatorTintColor = UIColor(red: 249/255, green: 207/266, blue: 224/255, alpha: 1)
return pc
()
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
let x = targetContentOffset.pointee.x
pageControl.currentPage = Int(x / view.frame.width)
// CONSTRAINTS OF BOTTOM CONTROLS
fileprivate func setupBottomControls()
let bottomControlsStackView = UIStackView(arrangedSubviews: [previousButton, pageControl, nextButton])
bottomControlsStackView.translatesAutoresizingMaskIntoConstraints = false
bottomControlsStackView.distribution = .fillEqually
view.addSubview(bottomControlsStackView)
NSLayoutConstraint.activate([
bottomControlsStackView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
bottomControlsStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
bottomControlsStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
bottomControlsStackView.heightAnchor.constraint(equalToConstant: 50)
])
// SUPER VIEW DID LOAD
override func viewDidLoad()
super.viewDidLoad()
collectionView?.backgroundColor = .white
collectionView?.register(newJobCellGeneral.self, forCellWithReuseIdentifier: "newJobCellGeneral")
collectionView?.register(newJobCellTechnical.self, forCellWithReuseIdentifier: "newJobCellTechnical")
collectionView?.isPagingEnabled = true
setupBottomControls()
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
return 0
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 2
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
if indexPath.item == 0
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "newJobCellGeneral", for: indexPath) as! newJobCellGeneral
navigationItem.title = "General Info"
return cell
else
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "newJobCellTechnical", for: indexPath) as! newJobCellTechnical
navigationItem.title = "Technical Specs"
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: view.frame.width, height: view.frame.height)
【问题讨论】:
【参考方案1】:流程是相反的,但是是的,最简单的方法是通过通知 在你的收藏视图中
把它放在你的collectionView按钮按下方法中
NotificationCenter.default.post(name: Notification.Name("handleNewJob"), object: nil)
在您的集合视图单元格中添加观察者(init 或 awakeFromNib 取决于)
NotificationCenter.default.addObserver(self, selector: #selector(handleNewJob, name: NSNotification.Name(rawValue: "handleNewJob"), object: nil)
【讨论】:
添加这两行后,我应该在handleNext
按钮中添加什么来调用函数?我只想在按下按钮时调用该函数。我现在有这个newJobCellGeneral.handleNewJob()
,我收到错误 Instance member 'handleNewJob' cannot be used on type 'newJobCellGeneral';您的意思是使用这种类型的值吗?
这段代码有效 - 但是我没有将第一行放入 viewDidLoad 中,而是将其放入我的按钮函数中,因此只有在点击时才会调用它。感谢您的帮助。【参考方案2】:
通知中心是一种解决方案,但更简单的方法是能够直接从单元格调用集合视图控制器上的函数。
为此,您需要能够引用您的父视图控制器。所以添加这个 UIView 扩展:
创建一个名为 UIView.swift 的 swift 文件并粘贴:
import UIKit
extension UIView
var parentViewController: UIViewController?
var parentResponder: UIResponder? = self
while parentResponder != nil
parentResponder = parentResponder!.next
if parentResponder is UIViewController
return parentResponder as! UIViewController!
return nil
然后从您的单元格中,例如单击按钮时:
@IBAction func someButtonAction(sender : UIButton)
let parent = self.parentViewController as! page_newJobSwipingController
parent.whateverFunction()
【讨论】:
我将第一块代码放在 UICollectionViewController 的底部,将第二块代码放在函数上方的单元格中。但是我在单元格中收到这些错误。对于 let 行 Value of type '(newJobCellGeneral) -> () -> (newJobCellGeneral)' has no member 'parent' 和第二行 Expected declaration。跨度> 创建一个名为 UIViewExtention 的新 swift 文件(但这个名称并不重要)并将第一个代码块放入其中。然后在你的单元格内,你想在父级上调用函数,使用第二个代码块。 我已经创建了新的 UIViewExtension 并复制了第一个块。当我将第二个文本块复制到我的 UIViewCollectionViewCell(类名:newJobCellGeneral)中时,我收到此错误Value of type 'newJobCellGeneral' has no member 'parent'
。
别担心我已经修复的错误。感谢您的帮助 - 我发现一旦代码放置在正确的位置,@zeck 的答案很容易工作。
因为你可能错过了 let parent = self.parentViewController as! page_newJobSwipingController 在同一个函数中以上是关于从 UICollectionViewCell 调用函数以在 UICollectionView 中使用的主要内容,如果未能解决你的问题,请参考以下文章
如何确定何时显示 UICollectionViewCell?
以编程方式在特定 UICollectionViewCell 内的 TableView?
- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath 未调用
UICollectionViewCell里面的UIWebView不调用Delegate方法