这个让我很难过,所以希望有人可以提供帮助。我有一个tableview,它有一个带有3个标签和2个按钮的自定义单元格。如果用户点击标签,我使用didSelectRowAtIndexPath从数组设置变量(即variable = array [indexPath.row]),然后执行segue,使用prepareForSegueWithIdentifier将信息从变量传递给新VC - 这很好用一切都很好。
我想在同一个单元格中为按钮实现相同的功能,但是我无法检测哪个行被点击。我已经尝试了一个IBAction来自我第二次编码“func didSelectRowAtIndexPath”的按钮,它有点工作但是行不准确(例如,它会传递一个单元格的信息,而不是我实际挖掘的那个单元格) - 我还尝试了一个全局变量,它将从原始的didSelectRowAtIndexPath函数中获取行,但结果类似。
这样做的最佳做法是什么?还有另一种方法可以从tableView中的第二个位置获取行吗?我应该使用其他标签而不是按钮吗?
非常感谢任何帮助/想法。如果需要,也很乐意发布我的代码。谢谢!!
import UIKit
import Parse
var rowNumber:Int = 0
class FeedTableViewController: UITableViewController {
var postToWeb:String = ""
var usernames = [String]()
var linkArr = [String]()
var titleArray = [String]()
var users = [String: String]()
var createdAt = [String]()
var userList: [User] = []
var sortedArticles: [User] = []
var commentUrl:String = ""
var commentTitle: String = ""
var commentUser:String = ""
struct User {
var date:NSDate
var username:String
var url:String
var title:String
}
let cellSpacingHeight: CGFloat = 10
class commentButtonClass: UIButton {
var section:Int = 0
}
@IBAction func commentButtonPressed(sender: AnyObject) {
commentTitle = self.userList[rowNumber].title
commentUrl = userList[rowNumber].url
commentUser = (PFUser.currentUser()?.username)!
performSegueWithIdentifier("commentView", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
var query = PFUser.query()
query?.orderBySortDescriptor(NSSortDescriptor(key: "createdAt", ascending: false))
query?.findObjectsInBackgroundWithBlock({ (objects, error) in
if let users = objects {
self.usernames.removeAll(keepCapacity: true)
self.linkArr.removeAll(keepCapacity: true)
self.titleArray.removeAll(keepCapacity: true)
self.createdAt.removeAll(keepCapacity: true)
for object in users {
if let user = object as? PFUser {
self.users[user.objectId!] = user.username!
}
}
}
let getFollowedUsersQuery = PFQuery(className: "followers")
getFollowedUsersQuery.whereKey("follower", equalTo: PFUser.currentUser()!.objectId!)
getFollowedUsersQuery.orderBySortDescriptor(NSSortDescriptor(key: "createdAt", ascending: false))
getFollowedUsersQuery.findObjectsInBackgroundWithBlock { (objects, error) in
if let objects = objects {
for object in objects {
let followedUser = object["following"] as! String
let query = PFQuery(className: "posts")
query.whereKey("userId", equalTo: followedUser)
query.orderBySortDescriptor(NSSortDescriptor(key: "createdAt", ascending: false))
query.findObjectsInBackgroundWithBlock({ (objects, error) in
//create a struct with createdAt as struct name since will be unique majority of time if include time and date.
if let objects = objects {
for object in objects {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
let dateString = dateFormatter.stringFromDate(object.createdAt!)
self.userList.append(User(date: object.createdAt!, username:self.users[object["userId"] as! String]!, url: object["linkURL"] as! String, title: object["title"] as! String))
self.userList.sortInPlace{ $0.date.compare($1.date) == NSComparisonResult.OrderedDescending }
self.tableView.reloadData()
}
}
})
}
}
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Set the spacing between sections
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return cellSpacingHeight
}
// Make the background color show through
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.clearColor()
return headerView
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return userList.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! cell
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
let dateString = dateFormatter.stringFromDate(self.userList[indexPath.section].date)
myCell.titleLabel.text = self.userList[indexPath.section].title
myCell.userLabel.text = self.userList[indexPath.section].username
myCell.createdDateLabel.text = dateString
myCell.rowNumberLabel.tag = indexPath.section
// add border and color
myCell.backgroundColor = UIColor.whiteColor()
myCell.layer.borderColor = UIColor.clearColor().CGColor
myCell.layer.borderWidth = 2
myCell.layer.cornerRadius = 0
myCell.clipsToBounds = true
return myCell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let currentCell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!;
rowNumber = indexPath.section
postToWeb = userList[indexPath.section].url
print(postToWeb)
performSegueWithIdentifier("webView", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "webView") {
// initialize new view controller and cast it as your view controller
let vc = segue.destinationViewController as! WebViewController
// your new view controller should have property that will store passed value
vc.passedValue = postToWeb
}
if (segue.identifier == "commentView") {
let commentVc = segue.destinationViewController as! commentsViewController
commentVc.passedCommentTitle = commentTitle
commentVc.passedCommentUrl = commentUrl
commentVc.passedCommentUsername = commentUser
}
}
在上面,“webView”的segue工作正常,数据通过。在commentView中 - 传递数据,但它不正确。
答案 0 :(得分:0)
这样做的最佳做法是什么?
你需要委托模式。见下面的例子。
CustomTableViewCell
类:
protocol CustomTableViewCellDelegate {
func customTableViewCell(cell: CustomTableViewCell, didTextInLabelChanged text: String)
}
class CustomTableViewCell: UITableViewCell {
var delegate: CustomTableViewCellDelegate?
func handeLabelTextChanged(text: String) {
delegate?.customTableViewCell!(self, didTextInLabelChanged: text)
}
// ... some other code
}
CustomViewController
类:
class CustomViewController {
// some code
}
class CustomViewController: UITableViewDataSource {
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = // dequeue the right cell
cell.delegate = self
return cell
}
}
class CustomViewController: CustomTableViewCellDelegate {
func customTableViewCell(cell: CustomTableViewCell, didTextInLabelChanged text: String) {
// do tableView update with changed text
}
}
当你看到所有“改变”(或“窃听”或其他)逻辑正在你的单元格中进行时。要通知控制器有关此更改的信息,您只需使用所有方法创建一个协议(在这种情况下,我通知我的控制器有关标签中的文本已更改),然后您需要创建一个var delegate: YourDelegate?
并在需要的地方调用它。下一步,您需要在控制器中实现“句柄”功能。这很简单。您只需要实施customTableViewCell()
中的CustomTableViewCellDelegate
功能,并将delegate
变量设置为self
CustomTableViewCell
。
<强>更新强>
当用户点击单元格内的按钮时,我需要来自该单元格的特定信息,基于indexPath.row
很简单。请记住,在您的控制器中,您实现了CustomTableViewCellDelegate
?因此,要从单元格中获取特定信息,您可以执行以下操作:
class CustomViewController: CustomTableViewCellDelegate {
func customTableViewCell(cell: CustomTableViewCell, didTextInLabelChanged text: String) {
// here you get `someVariable` from your cell.
// where `someVariable` you set in the `cellForRowAtIndexPath` controller's
// method
let info = cell.someVariable
// or, if for some reason you not save in your cell some data,
// but you need the `indexPath.row` to get this data you
// can find this `indexPath` like this:
if let indexPath = tableView.indexPathForCell(cell) {
let number = youArrayOfNumbers[indexPath.row]
}
}
}
答案 1 :(得分:0)
要获取被点击的UITableViewCell(作为按钮的动作),您有不同的选择:
1)使用Target-Action方法,例如:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! cell
//...More Code
myCell.myBtn.addTarget(self, action: "myActionMethod:", forControlEvents: .TouchUpInside)
//... More Code
return myCell
}
然后定义您的操作方法(注意, yourTbl 是 UITableView 的实例):
func myActionMethod(sender:UIButton){
//base on the hierarchy of the UI
//Suppose in this case:
//(UITableView)->(UITableViewCell)->(ContentView)->UIButton then:
if let tableViewCell = sender.superview?.superview as? UITableViewCell, indexPath = yourTbl.indexPathForCell(tableViewCell){
//Here you have the IndexPath
}
}
2)相同的想法,但基本上你要设置UIButton的Tag属性(到您的行单元格),并使用发送者(参数)上的Target-Action获得按钮的标记。