Swift 3:如何点击单元格内的按钮并传入该单元格的indexPath?
Swift 3: How do I tap a button inside cell and pass in that indexPath of that cell?
我正在编程做所有事情,避免故事板。我有一个 collectionView,一个包含用户名和密码的 Post
模型对象,当然我还有 collectionView 单元格。我遇到的问题是我的 collectionView 单元格中有一个按钮。我希望能够点击这个按钮并进入一个新的控制器。这是简单的部分。问题是我不仅要进入新控制器,还要传入我点击的按钮的特定 Post 单元格的特定用户名。我希望这是有道理的。基本上我想要一个 Post,就像任何社交媒体应用程序一样,我想转至 "profile" 并将该特定用户的用户名也传递给该配置文件控制器。我希望你能理解这一点。任何帮助都将非常非常感谢,因为我已经坚持了一段时间。我当然会标记为答案。谢谢大家...
class MyController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var posts = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .white
collectionView?.register(CustomCell.self, forCellWithReuseIdentifier: "cellId")
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 50)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CustomCell
cell.post = posts[indexPath.item]
cell.homeController = self
return cell
}
class CustomCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
var homeController: MyController?
var post: Post? {
didSet {
if let username = post?.username {
usernameLabel.text = username
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .blue
setupViews()
}
lazy var myButton: UIButton = {
let btn = UIButton()
btn.backgroundColor = .red
btn.setTitle("Push", for: .normal)
btn.isUserInteractionEnabled = false
btn.addTarget(self, action: #selector(handleTapped), for: .touchUpInside)
return btn
}()
let usernameLabel: UILabel = {
let label = UILabel()
label.textColor = .white
return label
}()
func handleTapped() {
let postController = PostController()
homeController?.navigationController?.pushViewController(postController, animated: true)
}
func setupViews() {
addSubview(myButton)
myButton.frame = CGRect(x: (self.frame.width / 2) - 25, y: (self.frame.height / 2) - 25, width: 50, height: 50)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
您没有使用 segue,而是您使用 navigationController
推送了 ViewController。所以用 postController
对象传递值。
func handleTapped() {
let postController = PostController()
//Pass the detail that you want
postController.selectedPost = self.post
homeController?.navigationController?.pushViewController(postController, animated: true)
}
现在在 PostController
中声明一个类型 Post
的实例 属性 名称 selectedPost
然后在 viewDidLoad
中使用该对象来分配你的 Labels
.
class PostController: UIViewController {
var selectedPost: Post?
override viewDidLoad() {
super.viewDidLoad()
self.yourLabel.text = self.selectedPost.username
}
我建议您告诉 UIViewController
您的 CustomCell
中的一个按钮已被单击。您可以添加协议,将 delegate
属性 添加到您的单元格,然后 MyController
必须符合协议。该函数还应传入已单击的单元格,您可以从 collectionView
.
中获取该单元格的 indexPath
protocol CustomCellDelegate: class {
func didSelectButton(in cell: CustomCell)
}
class CustomClass: UICollectionViewClass {
weak var delegate: CustomCelLDelegate?
func handleTapped() {
delegate?.didSelectButton(in: self)
}
}
然后在您的 MyController
class 中添加委托并遵守协议。
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CustomCell
cell.post = posts[indexPath.item]
cell.delegate = self
return cell
}
extension MyController: CustomCellDelegate {
func didSelectButton(in cell: CustomCell) {
if let indexPath = collectionView.indexPath(for: cell) {
let postController = PostController()
let post = posts[indexPath.row]
postController.post = post //pass the data
self.navigationController?.pushViewController(postController, animated: true)
}
}
}
您还需要向 PostController
添加一个 post
变量。
class PostController {
var post: Post!
}
我正在编程做所有事情,避免故事板。我有一个 collectionView,一个包含用户名和密码的 Post
模型对象,当然我还有 collectionView 单元格。我遇到的问题是我的 collectionView 单元格中有一个按钮。我希望能够点击这个按钮并进入一个新的控制器。这是简单的部分。问题是我不仅要进入新控制器,还要传入我点击的按钮的特定 Post 单元格的特定用户名。我希望这是有道理的。基本上我想要一个 Post,就像任何社交媒体应用程序一样,我想转至 "profile" 并将该特定用户的用户名也传递给该配置文件控制器。我希望你能理解这一点。任何帮助都将非常非常感谢,因为我已经坚持了一段时间。我当然会标记为答案。谢谢大家...
class MyController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var posts = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .white
collectionView?.register(CustomCell.self, forCellWithReuseIdentifier: "cellId")
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 50)
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CustomCell
cell.post = posts[indexPath.item]
cell.homeController = self
return cell
}
class CustomCell: UICollectionViewCell, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
var homeController: MyController?
var post: Post? {
didSet {
if let username = post?.username {
usernameLabel.text = username
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .blue
setupViews()
}
lazy var myButton: UIButton = {
let btn = UIButton()
btn.backgroundColor = .red
btn.setTitle("Push", for: .normal)
btn.isUserInteractionEnabled = false
btn.addTarget(self, action: #selector(handleTapped), for: .touchUpInside)
return btn
}()
let usernameLabel: UILabel = {
let label = UILabel()
label.textColor = .white
return label
}()
func handleTapped() {
let postController = PostController()
homeController?.navigationController?.pushViewController(postController, animated: true)
}
func setupViews() {
addSubview(myButton)
myButton.frame = CGRect(x: (self.frame.width / 2) - 25, y: (self.frame.height / 2) - 25, width: 50, height: 50)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
您没有使用 segue,而是您使用 navigationController
推送了 ViewController。所以用 postController
对象传递值。
func handleTapped() {
let postController = PostController()
//Pass the detail that you want
postController.selectedPost = self.post
homeController?.navigationController?.pushViewController(postController, animated: true)
}
现在在 PostController
中声明一个类型 Post
的实例 属性 名称 selectedPost
然后在 viewDidLoad
中使用该对象来分配你的 Labels
.
class PostController: UIViewController {
var selectedPost: Post?
override viewDidLoad() {
super.viewDidLoad()
self.yourLabel.text = self.selectedPost.username
}
我建议您告诉 UIViewController
您的 CustomCell
中的一个按钮已被单击。您可以添加协议,将 delegate
属性 添加到您的单元格,然后 MyController
必须符合协议。该函数还应传入已单击的单元格,您可以从 collectionView
.
indexPath
protocol CustomCellDelegate: class {
func didSelectButton(in cell: CustomCell)
}
class CustomClass: UICollectionViewClass {
weak var delegate: CustomCelLDelegate?
func handleTapped() {
delegate?.didSelectButton(in: self)
}
}
然后在您的 MyController
class 中添加委托并遵守协议。
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CustomCell
cell.post = posts[indexPath.item]
cell.delegate = self
return cell
}
extension MyController: CustomCellDelegate {
func didSelectButton(in cell: CustomCell) {
if let indexPath = collectionView.indexPath(for: cell) {
let postController = PostController()
let post = posts[indexPath.row]
postController.post = post //pass the data
self.navigationController?.pushViewController(postController, animated: true)
}
}
}
您还需要向 PostController
添加一个 post
变量。
class PostController {
var post: Post!
}