我正在尝试在单元格中实现“编辑”按钮。
到目前为止我做了什么:
MainController:
this
ImgItemCell:
class MainController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let imgCellId = "imgCellId"
override func viewDidLoad() {
collectionView?.backgroundColor = .white
collectionView?.register(ImgItemCell.self, forCellWithReuseIdentifier: imgCellId)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: imgCellId, for: indexPath) as! ImgItemCell
cell.editButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
return cell
}
func buttonPressed(){
print("buttonPressed !")
}
}
结果:该按钮无法点击。单击按钮时不会打印日志。
在android中,我通过按钮import Material
class ImgItemCell: UICollectionViewCell{
override init(frame: CGRect){
super.init(frame: frame)
setupViews()
}
...
let editButton: RaisedButton = {
let button = RaisedButton(title: "Edit", titleColor: .black) return button
}()
func setupViews(){
...
addSubview(editButton)
...
}
}
完成此操作,以执行每行的操作。我怎样才能在Swift 3中做同样的事情?
解决方案:(它为我工作)
大家好,谢谢你们提出的所有建议,他们更不用说我提出解决方案了。
我的问题的根本原因是视图层次结构(如@DatForis指出的那样)
说明:我想要一个单元格包含图像和按钮布局,以便我有如下的视图层次结构
OnClickListener
此层次结构以某种方式阻止了按钮的单击事件。
因此,我在层次结构中改变了一点
override func setupViews() {
super.setupViews()
addSubview(imgView)
addSubview(buttonLayout)
buttonLayout.addSubView(buttonList)
buttonList.addSubview(editButton)
buttonList.addSubview(shareButton)
}
和BAM!它就像一个魅力。
事实上,我需要正确解释层次结构对儿童的影响。
顺便说一下,我认为这里的大多数回复都是可行的解决方案,但我选择了@DonMag作为最终答案,因为它干净清晰,并且有一个很酷的回调控制器。
但同样,我的根本问题来自视图层次结构。
答案 0 :(得分:8)
您可能希望使用标记来实现更简单的方法,但是对于单元格内的按钮,我总是实现委托模式
protocol MyCollectionViewCellDelegate: class {
func button(wasPressedOnCell cell: MyCollectionViewCell)
}
class MyCollectionViewCell: UICollectionViewCell {
weak var delegate: MyCollectionViewCellDelegate?
var data: String = "DATA"
@IBAction func buttonWasPressed(sender: UIButton){
delegate?.button(wasPressedOnCell: self)
}
}
class MainViewController: UIViewController, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "reuse", for: indexPath) as! MyCollectionViewCell
cell.delegate = self
return cell
}
}
extension MainViewController: MyCollectionViewCellDelegate{
func button(wasPressedOnCell cell: MyCollectionViewCell) {
//do what you want with the cell and data
}
}
使用此方法将允许您在单元格内有多个按钮。为每个按钮使用不同的委托方法
答案 1 :(得分:7)
一种非常可靠和灵活的模式是为您的单元格分配“回调关闭”。将您的按钮操作处理程序放在单元格中,并让它“回调”到视图控制器。
这是一个基本示例(您应该可以使用自定义单元格实现它而没有问题):
//
// CViewWithButtonCollectionViewController.swift
// SWTemp2
//
// Created by Don Mag on 6/5/17.
// Copyright © 2017 DonMag. All rights reserved.
//
import UIKit
private let reuseIdentifier = "ImgItemCell"
class ImgItemCell: UICollectionViewCell {
// this will be our "call back" action
var btnTapAction : (()->())?
override init(frame: CGRect){
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViews()
}
let editButton: UIButton = {
let button = UIButton(type: UIButtonType.system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .white
button.setTitle("Edit", for: .normal)
return button
}()
func setupViews(){
// add a button
addSubview(editButton)
editButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
editButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
// add the touchUpInside target
editButton.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
}
func btnTapped() {
print("Tapped!")
// use our "call back" action to tell the controller the button was tapped
btnTapAction?()
}
}
class CViewWithButtonCollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let layout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
layout.itemSize = CGSize(width: 300, height: 100)
}
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ImgItemCell
cell.backgroundColor = .red
// set a "Callback Closure" in the cell
cell.btnTapAction = {
() in
print("Edit tapped in cell", indexPath)
// start your edit process here...
}
return cell
}
}
答案 2 :(得分:1)
我创建了相同的场景。唯一的区别是我使用了UIButton
而不是RaisedButton
。它工作得很好。
1。ImgItemCell
class ImgItemCell: UICollectionViewCell
{
//MARK: View Lifecycle Methods
override func awakeFromNib()
{
super.awakeFromNib()
setupViews()
}
let editButton: UIButton = {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 50))
button.setTitle("Edit", for: .normal)
return button
}()
func setupViews()
{
addSubview(editButton)
}
}
2. MainController
方法
//MARK: UICollectionViewDataSource
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: imgCellId, for: indexPath) as! ImgItemCell
cell.editButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
return cell
}
@objc func buttonPressed()
{
print("buttonPressed !")
}
答案 3 :(得分:0)
您的buttonpress
方法如何知道,您正在选择哪个单元格按钮。因此,您可以与tag
区分开来
加入cellForItemAtindexPath
ButtonObject.tag = indexPath.item
和
func buttonPressed(_ sender: UIButton)
{
print("buttonPressed ! \(sender.tag)")
}
答案 4 :(得分:0)
func setupViews() {
...
addSubview(editButton)
editButton.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
}
func buttonPressed(sender:UIButton){
print("buttonPressed !")
}
答案 5 :(得分:0)
如果未检测到UIButton上的触摸动作。
要在Custom UICollectionCell的UIButton上启用触摸操作,请在Custom UICollectionCell类中添加以下方法。
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
var view = myButton.hitTest(myButton.convert(point, from: self), with: event)
if view == nil {
view = super.hitTest(point, with: event)
}
return view
}