将变量从 customCell.xib 的按钮传递到另一个 UIViewController
Posted
技术标签:
【中文标题】将变量从 customCell.xib 的按钮传递到另一个 UIViewController【英文标题】:Passing a variable from a customCell.xib's button to another UIViewController 【发布时间】:2018-02-10 21:23:54 【问题描述】:我的自定义单元格有一个按钮,单击该按钮时,用户可以转到另一个 ViewControler。该按钮有一个带有用户 ID 字符串的 titleLabel。我想要做的是将用户带到一个新的 UIViewController,将单击按钮的 titleLabel(用户 ID)传递给新 View Controller 上的变量。这样,我可以使用该变量(用户 ID)从 firebase 获取更多信息并将其显示在 UI 视图控制器上。
在自定义单元格的 .xib 上,我打印 UID 以确保每个按钮都打印对应的 ID,它确实如此。我想不出办法将该 ID 传递给新的 ViewController。
我尝试在网上进行研究,发现您无法在 customCell.xib 上做 prepare(for segue) 或 performegue(WithIdentifier)。
我尝试过做委托,然后做协议,但仍然无法让它发挥作用。我是 Swift 的新手。任何帮助都会很棒,谢谢!
这是 customCell.Xib 的 Swift 文件:
class CustomCellTableViewCell: UITableViewCell
@IBOutlet weak var postImage: UIImageView!
@IBOutlet weak var nameLbl: UILabel!
@IBOutlet weak var descriptionLbl: UITextView!
@IBOutlet weak var profileImageBtn: UIButton!
@IBOutlet weak var profileImage: UIImageView!
@IBOutlet weak var view: UIView!
var btnSelected : Bool = false
var vcInstance: ProfilesTableVC?
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
view.clipsToBounds = true
view.layer.cornerRadius = view.frame.size.width / 2
profileImage.layer.cornerRadius = profileImage.frame.size.width / 2
descriptionLbl.alpha = 0.7
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
@IBAction func profileBtnPressed(_ sender: Any)
let passValue = UserProfileVC()
let profileTvC = ProfilesTableVC()
print (profileImageBtn.titleLabel!.text!)
var id = (profileImageBtn.titleLabel!.text!)
profileTvC.didSelectProfileBtn(senderID: id)
这是 tableViewController,我加载了所有内容(不是我想要传递值的地方)。我尝试在此处传递值,然后执行 prepareForSegue 将值传递给新的 UIViewController 但在 segue 发生后该值变为 nil。我只是包含 .xib 从表视图调用函数的代码。
class ProfilesTableVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate
let cell = CustomCellTableViewCell()
func didSelectProfileBtn(senderID: String)
senderIDArray.append(senderID)
var index = senderIDArray.count - 1
selectedCellUserID = senderIDArray[index]
performSegue(withIdentifier: "showSendersProfile", sender: Any?.self)
这是 UIViewController,我想在其中传递变量并使用该 ID 从 Firebase 显示更多信息
import UIKit
import Firebase
class UserProfileVC: UIViewController
let customCell = CustomCellTableViewCell()
let profileTvC = ProfilesTableVC()
@IBOutlet weak var profileImage: UIImageView!
@IBOutlet weak var nameLbl: UILabel!
var delegate : Any?
var getName = String()
var getsenderID = String()
let userDataRef = Database.database().reference().child("Users")
override func viewDidLoad()
super.viewDidLoad()
print("ID is: \(profileTvC.selectedCellUserID)")
let sender = getsenderID
print(sender)
【问题讨论】:
【参考方案1】:如果您不想使用协议,可以在 tableView - cellForRowAt 方法中向按钮添加目标,也可以在该方法中将标记设置为行索引值。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let profileCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! MoviewReviewCell
reviewCell.profileImageBtn.tag = indexPath.row
reviewCell.profileImageBtn.addTarget(self, action: #selector(tappedOnXibCellButton), for: .touchUpInside)
return reviewCell
@objc func tappedOnXibCellButton(sender: UIButton)
print(sender.tag)
performSegue(withIdentifier: reviewListToDetails, sender: sender.tag)
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
let identifier = segue.identifier
if identifier == "segueName"
let destViewController = segue.destination as! DestinationClassViewController
let selectedIndex = sender as! Int
let profileId = profilesList[selectedIndex].id
destViewController.profileId = profileId
【讨论】:
谢谢!起初它给了我一个错误,它不能转换类型为“UINavigationController”的值。我查找了错误并对以下代码进行了必要的更改: override func prepare(for segue: UIStoryboardSegue, sender: Any?) let identifier = segue.identifier if identifier == "showSendersProfile" let nav = segue.destination as! UINavigationController 让 destViewController : UserProfileVC = nav.topViewController 为! UserProfileVC 让 selectedIndex = sender as! int let profileId = profileArray[selectedIndex].userID destViewController.getsenderID = profileId 我认为这可能会造成“重用”问题,tableView.dequeueReusableCell(withIdentifier:)
将重用单元格,这意味着您第一次创建它(当您调用 dequeReusableCell
时),然后您 addTarget
,第二行可能有reused,然后你添加其他目标。这使得第二行的按钮有两个目标将依次执行,这意味着 TWO 发生在不同的发送者身上。在添加新的之前考虑使用.removeTarget(target:action:for:)
【参考方案2】:
您似乎创建了一个NEW ProfilesTableVC
,并尝试继续执行segue。新创建的不在您的视图堆栈中,也不在您的情节提要中。
您可以在返回 cellForRowAt
时添加它(当然是在 ProfilesTableVC
):
cell.vcInstance = self
然后在按钮中点击
@IBAction func profileBtnPressed(_ sender: Any)
print (profileImageBtn.titleLabel!.text!)
var id = (profileImageBtn.titleLabel!.text!)
vcInstance?.didSelectProfileBtn(senderID: id)
您可以使用协议/委托来做到这一点。我认为您尝试了,但您的试用有问题。
定义一个回调委托:
protocol CustomCellDelegate: AnyObject
func customCell(didSelectButton name: String)
您会注意到扩展 AnyObject
。这是为了允许weak
引用,尝试阅读Swift ARC
然后,在你的牢房里:
weak var delegate: CustomCellDelegate?
然后在profileBtnPressed(_ sender: Any)
@IBAction func profileBtnPressed(_ sender: Any)
var id = (profileImageBtn.titleLabel!.text!)
delegate?.customCell(didSelectButton: id)
当单元格出队时:
(cell as? CustomCellTableViewCell)?.delegate = self
【讨论】:
以上是关于将变量从 customCell.xib 的按钮传递到另一个 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章
如何将 SwipeCellKit 的自定义滑动功能用于从 .xib 文件创建的自定义单元格?