Adding UILongPressGestureRecognizer on a custom UITableViewCell - iphone

I have a UITableView with custom cells. In function tableView(cellForRowAtIndexPath:) I populate cells from an object's array in this way
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as CustomTableViewCell
cell.txtOne.text = array[indexPath.row].firstText
cell.txtTwo.text = array[indexPath.row].secondText
return cell
}
Now I want to add to the UITextField a UILongPressGestureRecognizer that changes the property .enabled of each UITextField (in this way I can make the UITextField editable).
I have no idea how to do.
I tried adding the UILongPressGestureRecognizer into the Main.Storyboard but I can't catch the action on the UITextField, I can only on the cell.
Can anyone help me?
I use Xcode Version 6.1.1

Related

How to show separate View(box) in between tableview in Swift

In this screen how to show (blue view) in between tableview rows
design image
code: in storyboard design i have given all static data in labels and images so with this below code i am getting all cells like above screen shot, but after three cells how to show blue box view, please suggest me
import UIKit
class ViewController: UIViewController , UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BidCell", for: indexPath)
return cell
}
There are two ways to do that:
Use a different UITableViewCell class (probably what you are looking for?)
Use sections
How?
You can either create a new UITableViewCell prototype cell in your storyboard or do it programmatically.
Create a custom UITableViewCell as such:
class OfferTableViewCell: UITableViewCell {
}
// If you are not using storyboards, add the following code
// in your viewDidLoad
tableView.register(OfferTableViewCell.self, forCellReuseIdentifier: "your_cell_id")
Then, you can dequeue the newly created cell at any index as such:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 10 // Index of the different cell
let cell = tableView.dequeueReusableCell(withIdentifier: "your_cell_id", for: indexPath) as! OfferTableViewCell
// Do cell configuration here
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "BidCell", for: indexPath)
return cell
}
}
Keep in mind that this cell is going to take the place of another cell if you are using an array as datasource, so using myArray.count for your numberOfRowsInSection would result in the last array element missing. You will have to take that into account.
Resources
Using multiple custom cells in a TableView
UITableView sections
Custom header for TableView sections

Add switch in UITableView cell in Swift

How can I embed a UISwitch programmatically in a tableView cell in Swift?
I'm doing it like that
let shareLocationSwitch = UISwitch()
cell.accessoryView = shareLocationSwitch
Here is way you can embed a UISwitch on a UITableView cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "yourcellIdentifire", for: indexPath) as! YourCellClass
//here is programatically switch make to the table view
let switchView = UISwitch(frame: .zero)
switchView.setOn(false, animated: true)
switchView.tag = indexPath.row // for detect which row switch Changed
switchView.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
cell.accessoryView = switchView
return cell
}
here is switch call beck method
func switchChanged(_ sender : UISwitch!){
print("table row switch Changed \(sender.tag)")
print("The switch is \(sender.isOn ? "ON" : "OFF")")
}
#LeoDabus Great! explanation.
Note: if your tableview may have more than one section then You should create a CustomCell subclassing UITableViewCell and configure your accessoryView inside UITableViewCell awakeFromNib method instead of table view cellForRowAt method. When dequeuing the reusable cell cast it to your CustomCell Here is sample from #LeoDabus
if you update the array with 3 elements and refreshing the table using self.tableView.reloadData() (for example after 2 second) you can see that with Xcode13 the switch values will be swapped and the example doesn't work. I have similar issue with my App when Xcode has been released to 13. try this: https://drive.google.com/file/d/1_1HuI_JFIYusNmsdyekGBWXsGznneiQ7/view?usp=sharing

can't set custom cell class's variable

I created a table view and cell is custom style, I did hook up the cell with custom class and cell's id in dequeueReusableCell(withIdentifier: , for:)function.
I added an image view in the cell, and add it as IBOutlet into custom cell class. In custom cell class, I created get and set variable called tableImage to change the image in the image view.
But in
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
I still can't set tableImage. The error shows Value of type UITableViewCell has no member tableImage.
Have you add as! yourCustomTableViewCell after the dequeueReusableCell function?
yourTableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! yourCustomTableViewCell

How to add a custom cell to a dynamicly generated tableview?

Nearly during a week i'm trying to figure out how i can append a static-/custom tableviewcell to a dynamically generated tableview. I'm populating the cells based on the data i'm getting from the database. Basically what i'm trying to accomplish is like the following picture from the app ClassDojo:
As you may know and see, you can add add as many groups as you want with the ClassDojo app, but the latest cell, in this case Voeg een nieuwe klas toe, will always stay at the bottom of the tableview. That's exactly what i'm trying to do.
What i tried to do till this moment is trying to calculate the latest cell in the tableview and trying to append my custom cell, but unfortunately i couldn't get my head around it.
I would really appreciate if someone can help me out with this.
Thanks in advance.
Please let me know if you guys need any code.
---------EDITED POST---------
I did accomplish to assign my custom cell thanks to #Slayter, but now i'm facing with the problem that my custom cell is immediately overwritten by my dynamically created cells (with Alamofire).
Any help would be appreciated.
ClassDojo iOS Engineer here! More than happy to share how we do this.
Like Slayter mentioned, we do
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count + 1 // Add one for your custom cell
}
But in addition we also do the following:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = nil;
if self.indexIsForCustomCell(indexPath) {
cell = tableView.dequeueReusableCellWithIdentifier(CustomCell.reuseIdentifier)
// Additional configuration
} else {
cell = tableView.dequeueReusableCellWithIdentifier(RegularCell.reuseIdentifier)
// Additional configuration
}
return cell
}
Where CustomCell looks something like this (not exact):
class CustomCell: UITableViewCell {
static let reuseIdentifier = "CustomCell"
// More code
}
And regular cell looks like:
class RegularCell: UITableViewCell {
static let reuseIdentifier = "RegularCell"
// More code
}
The reason your dynamic cells are getting overwritten is because of the line
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
Notice that you are using the same cellIdentifier regardless of whether or not it is the custom cell or the regular cells. This means that most likely you are doing the following:
self.tableView.registerClass(RegularCell.class, forIdentifier: "new group")
self.tableView.registerClass(CustomCell.class, forIdentifier: "new group")
When you should be doing:
self.tableView.registerClass(RegularCell.class, forIdentifier: RegularCell.reuseIdentifier)
self.tableView.registerClass(CustomCell.class, forIdentifier: CustomCell.reuseIdentifier)
OR
self.tableView.registerClass(RegularCell.class, forIdentifier: "regularCellReuseIdentifier")
self.tableView.registerClass(CustomCell.class, forIdentifier: "customCellReuseIdentifier")
By using the same identifier key, you are telling the UITableView to treat both cells as the same type. So when it needs to reclaim memory for a new cell being drawn on screen, it's going to use RegularCell and CustomCell interchangeably.
Hope this helped and thanks for checking out our App!
================= EDIT =================
Realized that I forgot to add the indexIsForCustomCell method. Here it is:
func indexIsForCustomCell(indexPath : NSIndexPath) -> Bool {
if self.myData.count > 0 {
return indexPath.section == 0 && indexPath.row == (self.myData.count+1)
}
return indexPath.section == 0 && indexPath.row == 0
}
It's pretty simple. You just need to tell the tableView to expect one more cell than what is in your data source.
Example
In your numberOfRowsInSection method, you will have something like this:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count + 1 // Add one for your custom cell
}
Then in your cellForRowAtIndexPath method you just need to add some custom logic for that indexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
if indexPath.row < myData.count {
// configure cell as normal
} else {
// Add your custom cell logic here
}
return cell
}

UIImage not appearing in prototype cells in UITableView (Swift)

I have created a UITableView Containing 10 cells, each of which have a UIImageView attached to them using auto-layout
The table is populated in my BackTableViewController by the code:
TableArray = ["Home Page", "Membership Card", "Recent News", "Fitness Schedule", "Training Log", "Pool Lap Calculator", "Martial Arts Schedule", "Pool Schedule", "Comments", "Acknowledgements"]
The issue is that none of these images appear in the table until the cell is selected while run. I am out of ideas as to why this is... anyone?
Thanks
Edit: BackTableViewController
import UIKit
class BackTableViewController: UITableViewController {
var TableArray = [String]()
var ImageArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
TableArray = ["Home Page", "Membership Card", "Recent News", "Fitness Schedule", "Training Log", "Pool Lap Calculator", "Martial Arts Schedule", "Pool Schedule", "Comments", "Acknowledgements"]
ImageArray = ["home-50.png","credit_card-50.png","info-50.png","math-50.png","news-50.png","report_card-50.png","weightlift-50.png"]
// Do any additional setup after loading the view.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TableArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(TableArray[indexPath.row], forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = TableArray[indexPath.row]
return cell
}
}
You only need one prototype cell with a reuse identifier. The clue is in the name "prototype". Think of them as blueprints all cells are based off.
In your view controller class (which should be a UITableViewDelegate if it is a UITableViewContoller) you specify the number of rows with this method:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourArray.count
}
This is the method that takes care of displaying the right info in the right row of the table.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//We create a cell from our prototype that we gave an identifier to in our storyborad.
let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell") as! UITableViewCell
//Create a single instance of an item from our items array. we use the indexpath.row that was passed into this method as the index for the array.
let item = yourArray[indexPath.row]
//You can go into your array and get the right info out regarding this row by using the indexPath.row
cell.textLabel?.text = item
cell.imageView?.image = UIImage(named: item)
//Finally this method returns the correctly configured cell fro the tableview to display.
return cell
}
Hope this helps.
Try giving "Center x" constraint instead of leading space for the image view, and you should give it width and height constraint also.
You need to set your cell identifier using Interface Builder in the Attributes Inspector:
Then in your cellForRowAtIndexPath you need to pass the cell identifier as you set before, something like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// set the identifier cell, not TableArray[indexPath.row]
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = TableArray[indexPath.row]
return cell
}
I hope this help you.