Add downward-pointing arrow in table view cell - ios

I am looking for a way to implement the bottom arrow like in Apple's Activity app.
I couldn't find anything similar in cell accessory type.
cell.accessoryType = UITableViewCell.AccessoryType.none
cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
cell.accessoryType = UITableViewCell.AccessoryType.detailDisclosureButton
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
cell.accessoryType = UITableViewCell.AccessoryType.detailButton
I know that I can insert a UIImage there but maybe there's a better solution for this problem. I am using the default disclosure indicator in other cells, so I want to keep the same design in my app.

The correct solution is adding a custom image asset and placing a UIImage in the cell's accessoryView.
A hacky solution -- that might not work -- that you could try would be to set the accessoryType to disclosureIndicator then try rotating the accessoryView by setting its transform to CGAffineTransform(rotationAngle: .pi / 2).

I don't think you can rotate the default disclosureIndicator.
Here comes the regular solution.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil) // dequeue as necessary
cell.backgroundColor = .lightGray
cell.textLabel?.text = "\(indexPath.row)"
let downArrow = UIImage(named: "down_arrow")
cell.accessoryView = UIImageView(image: downArrow)
return cell
}
White down arrow image at the end of this sentence.

Related

UITableView cell detailTextLabel text alignment not working

I'm trying to format the position of numbers in a UIViewController's detailTextLabel property. The numbers in the detailTextLabel part of the UIViewTable are too far to the right (as in the image).
I've tried:
cell.detailTextLabel?.textAlignment = .center
but it doesn't work. I've tried .left, .right, .justified and various settings in interface builder.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PracticeWord", for: indexPath)
let sortedPracticeWord = sortedPracticeWords[indexPath.row]
print("practiceWord is: \(sortedPracticeWord)")
let split = sortedPracticeWord.components(separatedBy: "::")
cell.textLabel?.text = split[0]
cell.textLabel?.textColor = UIColor.white
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView!.backgroundColor = UIColor(white: 1, alpha: 0.20)
cell.textLabel?.text = split[1]
cell.detailTextLabel?.text = split[2]
cell.detailTextLabel?.textAlignment = .center
print("cell is: \(cell)")
return cell
}
I would like each number to end just under the 'g' of the word 'wrong'.
I think what's happening here is that the detailTextLabel is being sized to fit the text length, and the whole label aligned to the right edge.
I'd try adding a whitespace to the text that you add to the detail text label.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PracticeWord", for: indexPath)
let sortedPracticeWord = sortedPracticeWords[indexPath.row]
print("practiceWord is: \(sortedPracticeWord)")
let split = sortedPracticeWord.components(separatedBy: "::")
cell.textLabel?.text = split[0]
cell.textLabel?.textColor = UIColor.white
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView!.backgroundColor = UIColor(white: 1, alpha: 0.20)
cell.textLabel?.text = split[1]
cell.detailTextLabel?.text = split[2] + " "
cell.detailTextLabel?.textAlignment = .center
print("cell is: \(cell)")
return cell
}
The detail text label is only displayed with the built in UITableViewCell styles, and it's not going to respect the alignment because the default styles will do their own thing and won't give you that much control. Which is just fine for simple stuff but quickly becomes a limitation for anything nontrivial.
If you want to control placement you'll need to define your own custom table cell with left and right UILabels, and constrain them exactly where you want them. Also bear in mind that if the user changes the system font size, you still may not line up with the 'g' character, so you might want to consider a different design, or just not worrying about that alignment.
See https://developer.apple.com/documentation/uikit/uitableviewcell/cellstyle for a description of the built in styles, but I suspect you'll need to create your own if the default style isn't doing what you want.
After creating custom cells by following this tutorial:
creating custom tableview cells in swift
It seems to be giving me what I originally intended.

Uncheck UITableview custom checkbox option in Swift

I am trying to make a custom checkbox list using the UITableview that allows single selections (I should however be able to select as many options as I want) and a custom UITableCell.
My custom cell contains a Label and an ImageView and all I want is to change the image contained in the IV on tap.
I am able to change the image from unchecked to checked in my didSelectRowAtIndexPath without a problem but I am having problems changing it back from checked to unchecked.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
print("tableView -> didSelectRowAtIndexPath")
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CustomCellVC
cell.backgroundColor = UIColor.clearColor()
cell.ivRiskCellImage.image = UIImage(named: "CheckedBox")
}
I tried to play with the highlighted state of the ImageView by adding the checkedbox image as the highlighted image and then turning it on and off but it only enters the if but ignores the if else if clicked again
if(cell.ivCellImage.highlighted == false)
{
print("Highligth is OFF")
cell.ivCellImage.highlighted = true
}
else if(cell.ivCellImage.highlighted == true)
{
print("Highligth is ON")
cell.ivCellImage.highlighted = false
}
as well as checking what image is inside the IV, this if-else block being completely ignored
if(cell.ivRiskCellImage.image!.isEqual(UIImage(named: "UncheckedBox")))
{
print("Is unchecked!")
cell.ivRiskCellImage.image = UIImage(named: "CheckedBox")
}
else if(cell.ivRiskCellImage.image!.isEqual(UIImage(named: "CheckedBox")))
{
print("Is checked!")
cell.ivRiskCellImage.image = UIImage(named: "UnheckedBox")
}
Moreover, when I manage to display the checkedbox image on click I get something like this
while if I try setting the checked box for all the cells in cellForRowAtIndexPath by adding this
cell.ivRiskCellImage.image = UIImage(named: "CheckedBox")
the checkbox tick is no longer semitransparent but white, as it should be
Any ideas? I spent quite some time trying to solve this without any luck.
Instead of let cell = tableView.dequeueReusableCellWithIdentifier... I would use
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomCellVC
This way you get a reference to the cell you want to change the image in. tableView.dequeueReusableCellWithIdentifier is meant to be used in delegate method tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) when you want to recycle your cells for better performance.
Also cell.ivRiskCellImage.image!.isEqual(UIImage(named: "UncheckedBox")) doesn't work, because UIImage(named: "UncheckedBox") creates a new UIImage, which isn't the same as the UIImage you want to check it against.
As fat i understand that you want to change image form Check and Uncheck and vice versa
There is mainly two methods of table view delegate
– tableView:didDeselectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
reference link : https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/#//apple_ref/occ/intfm/UITableViewDelegate/tableView:didDeselectRowAtIndexPath:
Although you can do same thing in – tableView:didDeselectRowAtIndexPath:
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
{
print("tableView -> didSelectRowAtIndexPath")
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CustomCellVC
cell.backgroundColor = UIColor.clearColor()
cell.ivRiskCellImage.image = UIImage(named: "**unCheckedBox**")
}

iOS where to put custom cell design? awakeFromNib or cellForRowAtIndexPath?

So, basically i made a custom cell from a nib, wish i apply a little custom design, like colors and shadows.
I found two ways of applying the styling:
awakeFromNib():
override func awakeFromNib() {
super.awakeFromNib()
//Container Card Style
self.container.layer.cornerRadius = 3
self.container.setDropShadow(UIColor.blackColor(), opacity: 0.20, xOffset: 1.5, yOffset: 2.0, radius: 1.8)
//Rounded thumbnail
self.thumb_image.setRoundedShape()
self.thumb_image.backgroundColor = UIColor.customGreyTableBackground()
//Cell
self.backgroundColor = UIColor.customGreyTableBackground()
self.selectionStyle = .None
}
cellForRowAtIndexPath: (inside the tableView wish will show the cell)
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//get cell type
let cell = tableView.dequeueReusableCellWithIdentifier("searchResultCell", forIndexPath: indexPath) as! SearchResultCell
//Container Card Style
cell.container.layer.cornerRadius = 3
cell.container.setDropShadow(UIColor.blackColor(), opacity: 0.20, xOffset: 1.5, yOffset: 2.0, radius: 1.8)
//Rounded thumbnail
cell.thumb_image.setRoundedShape()
cell.thumb_image.backgroundColor = UIColor.customGreyTableBackground()
//Cell
cell.backgroundColor = UIColor.customGreyTableBackground()
cell.selectionStyle = .None
//cell data
if(!data.isEmpty){
cell.name_label.text = data[indexPath.row].name
cell.thumb_url = data[indexPath.row].thumb_url
}
return cell
}
In terms of performance, wish one will be better? I've noticed that in a awakeFromNib() the design only does it once, so this is the better one?
As you mentioned awakeFromNib is only called once (when the cell is instantiated), if its setting stuff like background colors and stuff like that that wont change then its ok to do it there, cell customization (the data that the cell is showing) should be done during cellForRowAtIndexPath, so you should not check if the data is empty there rather, give it the data everytime the cell is returned, this will allow you to reuse cells and set the data as needed
Hope this helps
Daniel

Add "activity indicator" to TableView and restore to "disclosure indicator" in Swift

I have a TableView with each cells' accessory set to "disclosure indicator" which worked correctly.
Then, I decided to add an activity indicator while updating each cell with data from external sources. To accomplish this, I set:
cell.accessoryView = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
When I'm done loading data from external sources, I've lost my "disclosure indicator" (the arrow on the right side of the cell). What should I restore "cell.accessoryView" to?
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let item = items[indexPath.row]
var cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
// SET ACTIVITY INDICATOR HERE
if cell.accessoryView == nil {
let indicator = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
cell.accessoryView = indicator
}
let indicator = cell.accessoryView as! UIActivityIndicatorView
// ... some code here ...
switch (item.state) {
case .New:
indicator.startAnimating()
self.fetchExternalData(item, indexPath:indexPath)
case .Downloaded:
indicator.stopAnimating()
// I'D LIKE TO RESTORE THE DISCLOSURE INDICATOR HERE
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
// cell.accessoryView = ???
}
return cell
}
Oops, I just tried setting "cell.accessoryView = nil" and it worked.. I should have thought of that before posting :-(
of course you need to set
cell.accessoryType = UITableViewCellAccessoryNone;
before change accessoryView

Swift: UITableViewCell Automatic Row Height For style Subtitle

I have a tableView with 2 sections, the first section is for text the user inputed earlier, the other section for selections based on that text. The first section has a Default tableViewCell style, the second section has a style of Subtitle. The first section is just a single cell, and it sizes dynamically based on the amount of text without issue. The second section is multiple cells, with UITableViewCell.textLabel and UITableViewCell.detailText set. These are the cells that do not auto size properly at all, I don't know what I am doing wrong. Note: 1) I do have tableView.rowHeight = UITableViewAutomaticDimension set in the viewDidLoad() method. 2) I am not using prototype cells in the storyboard.
This article states that I "must have constraints on the contentView". I honestly have no idea what that means. I know what constraints are in terms of setting content on the storyboard. I just don't know what he means in this context or how I would go about that if I don't have prototype cells.
Also, I have to set two re-use identifiers, depending on which section it is. That way it doesn't try to reuse the cell/section I have set aside for the user's input text.
With all that said in mind, here's the code I have. I'm a newbie to Swift and developing for iOS in general so if you have suggestions/advice for refactoring feel free to let me know. I have commented out some things I have tried. Setting the row height to 66 does work, but that's not the goal here. I want it dynamic because I don't know what will change later on.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cellIdentifier = ""
if indexPath.section == 1 {
//tableView.rowHeight = 66
//tableView.rowHeight = UITableViewAutomaticDimension
cellIdentifier = "DistortionItem"
} else {
//tableView.rowHeight = 160
cellIdentifier = "NegativeThought"
}
var cell: UITableViewCell! = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell
if indexPath.section == 1 {
if cell == nil {
cell = UITableViewCell(style: .Subtitle, reuseIdentifier: cellIdentifier)
}
cell.textLabel?.text = distortionslist.distortions[indexPath.row].0
cell.detailTextLabel?.font = UIFont.systemFontOfSize(10)
cell.detailTextLabel!.text = distortionslist.distortions[indexPath.row].1
cell.textLabel?.numberOfLines = 0
cell.detailTextLabel?.numberOfLines = 0
//tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
//cell.textLabel?.sizeToFit()
//cell.detailTextLabel?.sizeToFit()
} else {
if cell == nil {
//println("Cell set to default")
cell = UITableViewCell(style: .Default, reuseIdentifier: cellIdentifier)
}
cell.textLabel?.font = UIFont.systemFontOfSize(12)
cell.textLabel?.text = entry.thoughtText
cell.textLabel?.numberOfLines = 0
//cell.textLabel?.sizeToFit()
}
return cell
}
Example screenshot:

Resources