I have the following problem:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// ...
println(indexPath.row)
}
My output goes like this:
1
0
1
0
The numberOfRowsInSection tells me that I've got 10 items:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.actionDto != nil){
println(self.actionDto?.count)
return self.actionDto!.count
}
return 0
}
I have checked this indexpath.row is starting from 1 instead of 0? but can't really follow the answer or solve my problem.
Actually i just want to tap a Label in the cell and do some other stuff. But i have to know exactly which row it was.
I thought about using didSelectRowAtIndexPath method. Then i have problem that if i tap on the label the didSelectRowAtIndexPath method isn't called. (I think because of more than one observer on this label. -> i have delegate method on this cell and the other one i suppose is the tableview.)
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let indexPath = tableView.indexPathForSelectedRow()
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! TimelineCell
println("The number of cell is \(currentCell.numberOfRowAtIndexPath)")
}
If i click into the cell but not on labels or images all works fine and i get the right number of row. Perhaps someone knows how i can add more than one "observer" on a label for example. So that my Selectormethod and didSelectRowAtIndexPath both knew about the label tapped in the cell. I think this could solve my problem that i can do my own Selectormethod with the knowledge of the right row.
For people who want to know what i mean with Selectormethod:
let gestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("labelPressed")) <-
label.addGestureRecognizer(gestureRecognizer)
func labelPressed() {
delegate?.switchToOwnProfil!()
}
The mysterious thing is, that the first output shows me first 1 and not 0 but perhaps i overlooked something.
Thanks in advance!
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// ...
yourLabel.tag = indexPath.row
let gestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("labelPressed:")) <-
yourLabel.addGestureRecognizer(gestureRecognizer)
println(indexPath.row)
}
and in your function
func labelPressed(label:UILable) {
println(label.tag)
delegate?.switchToOwnProfil!()
}
Related
My Situation: I want to save Data from an Array at Index X in an Row on Index X in Section 1.
My code is:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return setObjectToPass.count
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section \(section)"
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cellEmpty = tableView.dequeueReusableCellWithIdentifier("LabelCell")
var countCell = 0
while countCell < setObjectToPass.count {
let indexPaths = NSIndexPath(forRow: countCell, inSection: 0)
let cell = tableView.dequeueReusableCellWithIdentifier( "LabelCell", forIndexPath: indexPaths)
cell.textLabel!.text = String(setObjectToPass[countCell])
print(cell)
countCell+=1
return cell
}
My Problem is that only the first index of the Array SetObjectToPass is passed and set into the Cell.text
while counter < fetchResult?.count {
let set = fetchResult![counter]
counter+=1;
setObject.append((set.reps?.integerValue)!)
}
You are implementing the tableView(_:cellForRowAtIndexPath:indexPath:) method wrongly.
Remember, every delegate method in UITableViewDelegate is like asking you a question. For example, numberOfSectionsInTableView(_:) is like asking you "How many sections do you want in your table view?". You answer the question by returning a value.
tableView(_:cellForRowAtIndexPath:indexPath:) is similar. It asks a question as well. It asks "What should I display in the table row at this index path?"
In your code, it seems like you want to give multiple answers - looping through the array and attempting to return multiple times. But it doesn't work that way, you can only give one answer.
In the first iteration of the while loop, the execution hits return and stopped. That's why you only see the first table cell.
Thus, you should change your code so that it only gives one answer to the question:
let cell = tableView.dequeueReusableCellWithIdentifier("LabalCell")
cell.textLabel?.text = String(setObjectsToPass[indexPath.row])
return cell
Don't use the loop in cellForRowAtIndexPath delegate method. cellForRowAtIndexPath method call each row based upon numberOfRowsInSection count rows, simply use indexpath.row, Use this code,
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cellEmpty = tableView.dequeueReusableCellWithIdentifier("LabelCell")
let cell = tableView.dequeueReusableCellWithIdentifier( "LabelCell", forIndexPath: indexPaths)
cell.textLabel!.text = setObjectToPass[indexPath.row] as? String
return cell
}
hope its helpful
I'm new to iOS, swift. I have two sections in my tableView. I want to be able to do a longPressGesture on the second section, and not the first, enabling the user to reorder tableview cells in the second section. How would I do that in swift? Would anyone kindly provide a simple sample code in Swift?
Thanks for your help, much appreciated!
If you just want to reorder move the cell for the particular you may add some button/action to enable/disable reorder , there is delegate which you can use
Your code can be like this:
//enable editing in the tableview to true when you want to enable reorder in your case may on the UILongPressGestureRecognizer action
//In viewDidLoad()
tblView.editing = true//set it to false to complete the reorder
The delegate methods can be use like this:
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.None
}
func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
//get the reorder change in the path, you can do operation on the array
let itemToMove:String = arrData[fromIndexPath.row]//get the old path of item
arrData.removeAtIndex(fromIndexPath.row)//remove item from old path
arrData.insert(itemToMove, atIndex: toIndexPath.row)//at item at new path in array
}
func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
//write code to allow reorder in the particular section/indexpath
if indexPath.section == 0 {
return false
} else {
return true
}
// Return false if you do not want the item to be re-orderable.
}
func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
//check if the reorder is allow in the particular section/indexpath before the reorder is done, return the old path if you don't want to move at Proposed path
if sourceIndexPath.section != proposedDestinationIndexPath.section {
return sourceIndexPath
} else {
return proposedDestinationIndexPath
}
}
the UILongPressGestureRecognizer can be implemented on the tableview or the tableview cell based on the requirements
let longpress = UILongPressGestureRecognizer(target:self, action:#selector(HomeScreenTableViewController.longPressGestureRecognized))
tblView.addGestureRecognizer(longpress)
func longPressGestureRecognized() {
NSLog("Detected")
tblView.editing = true
}
or in tableview cell with same method as above
let longpress = UILongPressGestureRecognizer(target:self, action:#selector(HomeScreenTableViewController.longPressGestureRecognized))
cell.addGestureRecognizer(longpress)
I'm working on a project that needs something I never imagined to have. The app for iOS is directed to iPad due to size. To that question, I made a small prototype to show one of the parties to detail better.
This is a tableView where the functions and actions will happen.
And this is the Swift code:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let data:[String] = ["Row 0","Row 1", "Row 2","Row 3","Row 4","Row 5","Row 6"]
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:Cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! Cell
cell.labelText.text = self.data[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = self.tableView.cellForRowAtIndexPath(indexPath)
cell!.alpha = 0.5
}
}
What the app to do exactly?
Well, when a row is selected, the rows below it need to stay with the Alpha equal to 0.5.
Examples:
I touched the row 3
Action:
Row 1, Row 2 and Row 3 will keep the Alpha equal to 1.0
Row 4, Row 5 and Row 6 will keep the Alpha equal to 0.5
I touched in row 4
Action:
Row 1, Row 2, Row 3 and Row 4 will keep the Alpha equal to 1.0
Row 5, Row 6 will keep the Alpha equal to 0.5
.
.
.
Can someone help me?
You'd want to set the alpha value in the cellForRowAtIndexPath, then simply reload that row when its tapped. This should preserve the alpha for that cell and set alpha to 1 on every other cell, even if the the user scrolls the cell offscreen.
var selectedIndexPath:NSIndexPath?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
if let selectedIndexPath = self.selectedIndexPath where indexPath.row == selectedIndexPath.row {
cell.alpha = 0.5
} else {
cell.alpha = 1
}
cell.labelText.text = self.data[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.selectedIndexPath = indexPath
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
Make an integer variable "selectedCell", and in didSelectRowAtIndexPath, set it equal to indexPath.row, then tableView.reloadData()
In cellForRowAtIndexPath simply use an if statement to determine if indexPath.row is greater than "selectedCell". If so then set the alpha value to 0.5, otherwise set it to 1.0.
It is generally a good practice to change cell properties in cellForRowAtIndexPath, because every time it is called you risk overwriting changes you make to cells elsewhere in the code. Hope this helped.
Hi I am proposing below solution, please consider
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let data:[String] = ["Row 0","Row 1", "Row 2","Row 3","Row 4","Row 5","Row 6"]
var rowSelected:Int
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:Cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! Cell
cell.labelText.text = self.data[indexPath.row]
if rowSelected <= indexPath.row
cell!.alpha = 0.5;
else
cell!.alpha = 1.0;
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = self.tableView.cellForRowAtIndexPath(indexPath)
rowSelected = indexPath.row
tableView.reloadData()
}
}
I'm not sure if you are describing what you want it to do or the anormal behaviour.
There are two possibilities:
1) If you want the selection related alpha to render on a single row, you may want to override didDeselectRowAtIndexPath and set the alpha to 1.0 there.
2) You need to explicitly set the alpha after getting the cell from dequeueReusableCellWithIdentifier because you are not guaranteed to get a fresh cell instance every time.
The tableview will call cellForRowAtIndexPath for a variety of reasons even after showing it for the first time. What is probably happening is that cellForRowAtIndexPath is called for rows that have been deselected and dequeueReusableCellWithIdentifier may or may not reuse an existing cell object. When it reuses a cell object, properties are not reset.
How can I make a static table view to create an action when one of the cells is clicked in Swift?
I have created a static table like a general menu of the app, I can directly create a push segue when one of the cells are clicked. But at the same time when I click to one of the seques, I want the below function to be run. By draging a cell to the UITableView in storyboard the create action option is not appearing.
var goToProfiles = PFObject(className: "goToProfile")
goToProfiles["user"] = PFUser.currentUser()!.username
goToProfiles["goToUser"] = usernameLbl.text
goToProfiles.save()
If you use sections you will also need to query them.
override func tableView(tableView: UITableView,
didSelectRowAtIndexPath indexPath: NSIndexPath) {
print(indexPath.section)
print(indexPath.row)
if indexPath.section == 1 && indexPath.row == 1 {
// do something
}
}
I found the solution with the code below:
override func tableView(tableView: UITableView,
didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == 1 {
//here you can enter the action you want to start when cell 1 is clicked
}
}
For swift 3 compatibility:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Your action here
}
I've been going in circles for a while and nothing I've found in related posts seems to solve it.
I'm programmatically adding a table to a custom UIView. The table and row text displays correctly, but neither didSelectRowAtIndexPath nor willdSelectRowAtIndexPath fire when I run this on the simulator and try to click on any of the rows.
The relevant bits of my code below:
import UIKit
import AVFoundation
#IBDesignable
class PerformanceQuestionView: UIView, UITableViewDelegate, UITableViewDataSource {
var optionsTable = UITableView(frame: CGRectMake(10,200,250,200))
var optionItems = ["One", "Two", "Three", "Four"]
convenience init(rect: CGRect, performanceQuestion:PerformanceQuestion?) {
self.init(frame: rect)
NSLog("PerformanceQuestionView.init()")
self.optionsTable.dataSource = self
self.optionsTable.delegate = self
self.optionsTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.optionsTable.allowsSelection = true
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
NSLog("numberOfRowsInSection")
return optionItems.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
NSLog("cellForRowAtIndexPath")
var cell:UITableViewCell = self.optionsTable.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel.text = self.optionItems[indexPath.row]
return cell
}
func tableView(tableView: UITableView!, willSelectRowAtIndexPath indexPath: NSIndexPath!) -> NSIndexPath! {
NSLog("You will select cell #\(indexPath.row)!")
return indexPath
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
NSLog("You selected cell #\(indexPath.row)!")
}
override func layoutSubviews() {
super.layoutSubviews()
self.addSubview(optionsTable)
}
}
Removing the TapGestureRecognizer worked for me!!!
// var backgoroundTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
// self.view.addGestureRecognizer(backgoroundTap)
Reason for this could be, you are using a pan gesture in the view. like AAA mentioned removing your pan gesture will do the trick. But if you still want to use the pan gesture you could do the following
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
view.addGestureRecognizer(tap)
tap.cancelsTouchesInView = false
Making cancelsTouchesInView, false will enable all you taps.
Remove the exclamation points:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
You need to add below code for Tap or Pan gesture.You need to tap.cancelsTouchesInView = false
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
view.addGestureRecognizer(tap)
tap.cancelsTouchesInView = false
OR
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.mainBlurViewAction))
mainBlurView.addGestureRecognizer(gesture)
gesture.cancelsTouchesInView = false
Then it will work
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Call According requirement
}
I have the same problem long time, I am for thinking it's a bug in UITableView programmatically when creating a UIView class.
My temporary solution and although it is not a good idea, but it works. It is to place a button the size of the cell and have an action dispatched by a protocol, to achieve at least simulate this action.
It is not good practice but could not stay stuck there longer.
For Swift 3.0, you need to use this function exactly:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Input your code here
}
Look very closely to make sure you are using this function. The compiler won't complain if you have NSIndexPath or you don't have _ before tableView but it won't work. So use this function, put a breakpoint in and you will see it go to that point when you tap on a row.
I was testing this with a static table (all static content cells).
This was deprecated in Swift 3:
override func tableView(_ tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
...
}
And replaced with:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
...
}
I tried all of the methods listed in this question and others. I finally deleted the table from my storyboard and started again.
In my storyboard, I added back the table, added a prototype cell. I connected the ViewController to the table. I connected the table to my dataSource and delegate methods.
I named the prototype identifier in the Attributes Inspector.
This worked for me. I did not apparently have any code to change.