Put checkmark in the left side of UITableViewCell - iphone

I want to make something similar to the WiFi settings page: when you tap the table cell, put a checkbox in the left side of the cell, and have a disclosure button accessory view on the right to show more details.
My question: is there a way to put the checkmark in the left side of a UITableViewCell without building a custom UITableViewCell ?

The answer is YES! You don't have to create a custom cell for that or add image views. To simulate checkboxes you only have to prepend a unicode symbol for a checkbox state to the cell text.
The unicode symbols I'm using for checkboxes are \u2705 for checked and \u2B1C for unchecked (nearly the same as \U0001F533 on iOS 5). iOS renders several unicode symbols as icons.
Here are some other symbols:
#"\u2611", #"\u2B1C", #"\u2705", #"\u26AB", #"\u26AA", #"\u2714", #"\U0001F44D", #"\U0001F44E"
Imitating the Wi-Fi settings page (with UITableViewCellStyleValue1):
cell.textLabel.text = #"\u2001 Wi-Fi 1";
cell.detailTextLabel.text = #"\U0001F512 \u268A";
cell.textLabel.text = #"\u2001 Wi-Fi 2";
cell.detailTextLabel.text = #"\U0001F512 \u268C";
cell.textLabel.text = #"\u2713 Wi-Fi 3";
cell.detailTextLabel.text = #"\U0001F513 \u2630";

Of course you can do that :) For example use UITableViewCellStyle
UITableViewCellStyleDefault,
// Simple cell with text label and optional image view
//(behavior of UITableViewCell in iPhoneOS 2.x)
...and put a custom "checkmark" image in that "optional image view".

In Swift you can press Command + Ctrl + Spacebar to show emoticons and special characters or you can copy this ✓ ✔️

So here is a way to do it. Place a UIImageView on the left edge of the cell. Do not set an image so it's blank as a start.
Then, assuming you are doing a custom cell and a class for that UITableViewCell, do something like this:
import UIKit
class MyCustoTableViewCell: UITableViewCell {
#IBOutlet weak var commandOption: UILabel!
#IBOutlet weak var checkMarkImage: UIImageView!
// Sets a left side checkmark on a cell when selected
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.checkMarkImage.image = selected ? UIImage(named: "BlueCheck") : .None
self.commandOption.font = selected ? UIFont(name: "Avenir-Heavy", size: 22) : UIFont(name: "Avenir-Book", size: 22)
// more check mark on the right side
// self.accessoryType = selected ? .Checkmark : .None
}
}
Note the bottom commented out is if you want the checkmark on the right. The super.setSelecdted method fires when a the user has tapped on the table cell. Be sure you have this implemented also:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// do any changes needed here or leave blank if just adding check
}
}
Finally, make sure you have #2x and #3x check mark PNGs assets in your Assets folder. Note those are called "BlueCheck" in this example but use what ever your check mark assets are called.
This approach makes sure that when a user selects a new row the check mark goes away on the current cell.
In this case I'm bolding the text that is to the right of the image view to further indicate it was the selected row.

No. You have to create a custom cell for that.

You should look at the UITableViewCell reference and Table View Guide. Use standard cell style with editingAccessoryType property set to UITableViewCellAccessoryCheckmark.

Related

UITableViewCell with undetermined number of items

I need to make a cell with some buttons. This buttons are answers options to a question. But the question and the number of buttons (answers) are not determined because I get these data from Alamofire. So there may be 2, 3, 6, or any number of buttons.
Is there a way to add these buttons programmatically depending on (for example) the number of items in an array, in a way that they look well constrained? Like a stack view?
Thanks in advance
A stack view is certainly a way of constraining any number of views into a column (or row). So that sounds like the best way to go.
This is a sneaky way to do it, but if you know the maximum number of buttons you're going to have, you can add it directly to your custom prototype cell on your storyboard without adding buttons programatically.
Solution (Written in Swift 4, but a general answer)
Assuming there is a maximum of 8 answers in any question, create 8 buttons in your custom prototype cell. Add constraints as you like to make them look pretty!
Remember to give your cell a unique identifier ("CustomCell" in my case).
Go to File > New File > Cocoa Touch Class > Select "TableViewCell" Subclass
& give it an appropriate name (in my case CustomCellTableViewCell.swift). This will contain all your UI components outlets.
Select the prototype cell in your storyboard. Navigate to the third icon from the left and select "CustomCellTableViewCell" as your class.
Control+Drag outlets of your buttons and fields that you're going to be working with from the storyboard to your newly created CustomCellTableViewCell.swift. The file should now look something like this:
class CustomCellTableViewCell: UITableViewCell {
#IBOutlet weak var question: UILabel!
#IBOutlet weak var answerOne: UIButton!
#IBOutlet weak var answerTwo: UIButton!
...
...
#IBOutlet weak var answerEight: UIButton!
}
The next few steps will be in the TableviewDataSource function func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell. Remember to cast the TableviewCell as a CustomCell:
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCellTableViewCell
Put all the answer buttons in an array
var answerButtons = [cell.answerButtonOne, cell.answerButtonTwo..., cell.answerButtonEight]
Now you can set the answer button text in a loop as follows:
for i in 0..<answerButtons.count {
if i < data[indexPath.row].answers.count { // if the answer exists, add it to the button
cell.answerButton[i].isHidden = false // show button if answer exists
cell.answerButton[i].setTitle(data[indexPath.row], for: .normal)
} else {
cell.answerButton[i].isHidden = true // hide that button
}
}

How can i make several labels clickable in a shortcut?

in my code i have a tableView and several labels..
I want that the when the user click on cell and after that click on one of the labels, the text in the label will be same as the text in the row that be clicked.
Q1. How can i enable all labels to be clickable and connect to one function that will point on the specific label each time the user click on it?
Q2. I tried to make the same gesture to all labels with UITapGestureRecognizer.. apparently this gesture refers only to the last label (Lbl4 down here in code example).. it means that the text in Lbl1 in my func change only by clicking on Lbl4.. why is that? and how can i change it that it will refers to all labels?
override func viewDidLoad() {
super.viewDidLoad()
let aSelector : Selector = #selector(ViewController.lblTapped)
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector)
tapGesture.numberOfTapsRequired = 1
Lbl1.addGestureRecognizer(tapGesture)
Lbl2.addGestureRecognizer(tapGesture)
Lbl3.addGestureRecognizer(tapGesture)
Lbl4.addGestureRecognizer(tapGesture)
}
func lblTapped(){
Lbl1.text = self.currentPlayerChooseInRow
}
Thanks for advance...
Firstly, you need to understand UITableView object. UITableView is an array of cells, ok? Then, you need use some methods associated to UITableView like numberOfRowsInSection (where app knows the number of cells) and cellForRowAtIndexPath (where app knows cell will be)
About your questions, i recomend you to use outlets to connect labels, buttons, objects to the controller (try to not use gestures if it is not necessary)
Finally, object cells are programmed into cell. If you have a complex cell, you will need a custom cell controller.

Swift - Button action not triggered in table view cell

I have a ViewController who contains a TableView. I want in each cell, a red button who did something (let's say 'hello' for test), or when I touch the cell anywhere but not on the button I perform a segue.
But even when I touch the button, it's the segue who perform. I tried some search on SF but none of the questions help me...
I don't know if that's usual but when I touch the cell, all the row white background become gray, even the background of the red button.
In storyboard I have this cell hierarchy :
The user interaction is enabled on both cell and button.
In the questions I found they said, on the cell set 'accessory' on 'disclosure indicator', I did it, but if it's possible I would like to keep it at 'None'.
Also I set a custom class for the cell, here is the code :
class MyTableViewCell: UITableViewCell {
#IBOutlet weak var rentButton: UIButton? // I use this class for 2 tableview almost similar, but in the other I don't have the redButton, that's why I put an '?'
}
I also set the delegate and datasource of the tableView to my ViewController, here is the code of my view controller :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MyTableViewCell
cell.rentButton!.tag = indexPath.row
cell.rentButton!.addTarget(self, action: #selector(MyViewController.rent(_:)), forControlEvents: .TouchUpInside)
return cell
}
// Rent() is never called:
func rent(sender: UIButton) {
print("here \(sender.tag)")
}
EDIT : The solution was to put out the button from the conainer view !
You can stop the segue from actioning when the button is pressed by performing it programatically. You can do the following:
Remove your segue that goes from the cell to another view controller and change it go from the TableViewController to the other view controller
Create a variable in your TableViewController class such as: var buttonPressed = false
In your button action set buttonPressed to true
In didSelectRow, check that buttonPressed is not true then performSegue and change buttonPressed to false, else do nothing
As discussed, move the button from the container to the content view

YPDrawSignatureView - Table scrolling when drawing signature

So I want a signature view within a table cell. Obviously whenever somebody tries to draw in the cell, the table scrolls.
How would I stop the scrolling but ONLY when the user is writing in the signature box?
I found better solution for this issue rather than putting button. Implement the delegate methods in viewController,
class mainVC: UIViewController,YPSignatureDelegate {
Than set delegate of signature view to this view controller
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SignatureCell", for: indexPath) as! SignatureCell
cell.signatureView.delegate = self
return cell
}
And then add these code. This are two delegates of YPSignature. Add in Main view controller
func didStart() {
tableView.isScrollEnabled = false
}
// didFinish() is called rigth after the last touch of a gesture is registered in the view.
// Can be used to enabe scrolling in a scroll view if it has previous been disabled.
func didFinish() {
tableView.isScrollEnabled = true
}
I would solve this with a button covering the cell, and when the user taps it, the cell displays the YPDrawSignatureView. Just before the signature view is shown, disable the scrolling:
tableView.scrollEnabled = false
Later when you save the signature, enable scrolling again by setting scrollEnabled to true.
I added a uitableview and custom cells. In one of the custom cells contain a button(ex. addSignatureButton) on the top of signatureView.
I used delegate method to communicate between uitableviewcell and uiviewcontroller. A delegate is added to UITableViewCell to notify whether the addSignatureButton is tapped. Once it is tapped, addSignatureButton is hidden, signatureView is visible and the tableview's scroll is disabled. When user finishes adding signature, signatureView is hidden, addSignatureButton is visible and tableview scroll is enabled.
https://github.com/alvinvgeorge/DrawSignatureOnTableViewCell

Use tags for tableView inside UIViewController to update Labels

I added a table view to my UIViewController. then i added a label to my custom cell inside the table view. i tried to update labels inside the tableview by using tags. seems it does not working.
this is my code.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("LineItemCell", forIndexPath: indexPath)
let object = lineItemsObject[indexPath.row]
//cell.textLabel?.text = object["quantity"]
print(object["description"]!)
if let descriptionLabel = cell.viewWithTag(500) as? UILabel {
descriptionLabel.text = object["description"]
}
else
{
print("fail")
}
return cell
}
When i call the function always it does not read the tag and prints "fail". i have assigned correct tag value to my label also.
here i have attached a image of my label details in attribute inspector
Please help me the fix the issue.
As #TheAppMentor said code looks fine. Make sure you entered correct cell identifier. Then make sure you connected your view controller to correct class (it's my common mistake). Also make sure that something else in this cell hasn't the same tag. You can also print all subviews to check what's inside.
Your cell is not knowing about your label inside (the one with 500 tag). You are not providing a custom cell, because of this line:
let cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("LineItemCell", forIndexPath: indexPath)
This is a predefined cell. As of documentation you can have predefined cells or custom ones (obtained by subclassing UITableViewCell):
"When creating cells, you can customize them yourself or use one of several predefined styles. The predefined cell styles are the simplest option. With the predefined styles, the cell provides label and image subviews whose positions and styling are fixed. ... To set the text and images of the cell, use the textLabel, detailTextLabel, and imageView properties."
If you want to go predefined:
If you want to just put the text onto cell use (I see this one is commented on first place).
cell.textLabel?.text = object["quantity"]
Go custom
Extend UITableViewCell on a separate swift file. Do your bindings here and work with your storyboard in parallel. Assign the custom class to your cell. Also, change dequeue:
let cell: MyCustomTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("LineItemCell", forIndexPath: indexPath) as! MyCustomTableViewCell