UITableViewCell - selected background size based on content - ios

I have this code to get table cell
func getCell(_ tableView: UITableView) -> UITableViewCell? {
var cell:UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: CELL_REUSE_ID)
if (cell == nil)
{
//init and configure the cell
cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: CELL_REUSE_ID)
let selectedView:UIView = UIView(frame: CGRect(x: 0, y: 0, width: cell!.frame.size.width, height: cell!.frame.size.height))
selectedView.backgroundColor = UIColor.black.withAlphaComponent(0.3)
let layer = selectedView.layer
layer.borderColor = UIColor.blue.cgColor
layer.borderWidth = getCellBorderWidth();
layer.cornerRadius = getCellCornerRadius();
layer.backgroundColor = UIColor.blue.cgColor
cell!.selectedBackgroundView = selectedView
}
return cell
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell:UITableViewCell? = getCell(tableView)
cell!.backgroundColor = UIColor.clear
cell!.textLabel!.textColor = UIColor.darkText
cell!.textLabel!.text = tableData[indexPath.row]
cell!.textLabel!.textAlignment = .right
cell!.textLabel!.numberOfLines = 1
cell!.textLabel!.adjustsFontSizeToFitWidth = true
return cell!
}
Cells and table are generated in code, no xibs. Now, If I select cell, the background is covering entire width of table. How can I do background for some cells, that is only half of the table width (or some other percentual ratio)?

I think U can add another view to selectedBackgroundView
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
// selectedBackgroundView
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor(white: 0, alpha: 0)
// add another view to selectedBackgroundView, and set any frame for this view
let selectView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 40))
selectView.backgroundColor = .red
backgroundView.addSubview(selectView)
cell?.selectedBackgroundView = backgroundView
}
return cell!
}

Related

How to transform Delete option in Tableview cell

I've transformed the tableview and tableview cell to fill the cell from bottom to top using How to populate UITableView from the bottom upwards? post.
But I want to transform the swipe to Delete option as well.
Please refer the image for more detail.
You can see the Delete option is not transform as the tableview.
Any helpful answer will be very appreciated.
First reverse UITableView in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
tableView.transform = CGAffineTransform(scaleX: 1, y: -1)
}
Then reverse the cell in cellForRowAt.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCell", for: indexPath) as? MyTableViewCell else { fatalError() }
cell.transform = CGAffineTransform(scaleX: 1, y: -1)
cell.contentView.transform = CGAffineTransform(scaleX: 1, y: -1)
return cell
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .default, title: nil) { (action, indexPath) in
// delete item at indexPath
}
let label = UILabel(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 75, height: tableView.rectForRow(at: indexPath).height)))
label.numberOfLines = 0
label.textAlignment = .center
label.textColor = UIColor.white
label.backgroundColor = UIColor.red
label.text = "Delete"
UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
label.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let cgImage = image?.cgImage {
let rotada3 = UIImage(cgImage: cgImage, scale: image!.scale, orientation: .downMirrored)
delete.backgroundColor = UIColor(patternImage: rotada3)
}
return [delete]
}
Here on editActionsForRowAt I did a work around to print image with mirrored text
Transform tableview
tableView.transform = CGAffineTransform(rotationAngle: -(.pi))
Then within cell
cell.transform = CGAffineTransform(rotationAngle: .pi)

iOS Swift, how to delete a UIView in a TableViewCell and adjustment cell height?

I want to add or delete some view in a TableViewCell dynamically
And I want the cell Height could be adjusted to the cell content height when I delete the UIView in cell.
below is my demo, I use the
self.frame.size.height -= 100
to adjust cell height, but the result is not so good.
import UIKit
import SnapKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let table = UITableView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 1200))
table.dataSource = self
table.delegate = self
table.estimatedRowHeight = 1
table.rowHeight = UITableView.automaticDimension
table.separatorColor = UIColor.blue
table.register(CustomCell.self, forCellReuseIdentifier: "identifierid")
view.addSubview(table)
}
}
class CustomCell:UITableViewCell {
let btn:UIButton = {
let btn = UIButton()
btn.layer.borderColor = UIColor.black.cgColor
btn.layer.borderWidth = 1
btn.setTitle("delete red view", for: .normal)
btn.setTitleColor(UIColor.black, for: .normal)
return btn
}()
let v:UIView = {
let v = UIView()
v.backgroundColor = UIColor.red
return v
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.contentView.addSubview(btn)
btn.snp.makeConstraints { (make) in
make.top.equalToSuperview().offset(10)
make.size.equalTo(CGSize(width: 150,height: 50))
}
btn.addTarget(self, action: #selector(deleteCellImg), for: .touchUpInside)
self.contentView.addSubview(v)
v.snp.makeConstraints { (make) in
make.top.equalTo(btn.snp.bottom)
make.left.equalTo(btn)
make.size.equalTo(CGSize(width: 100, height: 100))
make.bottom.equalToSuperview().offset(-10)
}
}
#objc func deleteCellImg() {
v.removeFromSuperview()
self.frame.size.height -= 100 //100 is the red view height
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension ViewController:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 6
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "identifierid", for: indexPath) as! CustomCell
return cell
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
The result is showed below
When I delete a view in a cell,I don't want the other cell height would be influenced.So is there some detail I ignore?
call removeFromSuperview() while removing the view. This will be done in your Custom Cell class.
Then reload table view through table.reloadData().
If the row height is still misleading use constraints or height for row.

Auto adjust font size for UITableView

For one of my UITableView, to allow more text or large font size text to fit in the fields, I need to add or adjust font size.
I used a boolean for adjustsFontSizeToFitWidth. And clipsToBounds=true. But this does not always work for me, not sure why it's inconsistent, especially when you have bigger font size text to be included. Any correction?
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
let headerLabel = UILabel(frame: CGRect(x: 40, y: 0, width:
tableView.bounds.size.width, height: tableView.bounds.size.height))
headerLabel.textColor = UIColor.white
headerLabel.text = self.tableView(self.tableView, titleForHeaderInSection: section)
headerLabel.sizeToFit()
headerLabel.adjustsFontSizeToFitWidth = true
headerLabel.clipsToBounds=true
headerLabel.numberOfLines=0
headerLabel.lineBreakMode = NSLineBreakMode.byTruncatingTail
headerLabel.minimumScaleFactor = 0.2
headerView.addSubview(headerLabel)
return headerView
}
Delete the following may be?
headerLabel.sizeToFit()
This will allow to make 
adjustsFontSizeToFitWidth
 property working.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if searching {
cell?.textLabel?.text = searchedLabour[indexPath.row]
cell?.textLabel?.sizeToFit()
cell?.textLabel?.adjustsFontSizeToFitWidth = true
cell?.textLabel?.numberOfLines = 2
cell?.textLabel?.lineBreakMode = NSLineBreakMode.byTruncatingTail
} else {
cell?.textLabel?.text = labourWordsArray[indexPath.row]
cell?.textLabel?.sizeToFit()
cell?.textLabel?.adjustsFontSizeToFitWidth = true
cell?.textLabel?.numberOfLines = 2
cell?.textLabel?.lineBreakMode = NSLineBreakMode.byTruncatingTail
}
return cell!
}

Assign an upper bound for the height of a tableview?

I have a tableview whose height is dynamically adjusted. The height is adjusted so that the tableview only includes a certain number of rows, and no empty rows. So, if there are only 2 rows then the height is smaller, and if there are 4 rows then the height is bigger. However, I do not want its height to go past a certain point. How can I allow the height to be dynamically adjusted, while not letting the height ever reach past a certain point?
This is my code:
#IBOutlet var tableView: UITableView!
#IBOutlet var tableViewHeightConstraint: NSLayoutConstraint!
var items: [String] = ["Swift", "Is", "So", "Amazing"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "Cell") as! UITableViewCell
// Make sure the table view cell separator spans the whole width
cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
cell.textLabel?.text = self.items[indexPath.row]
return cell
}
override func viewWillAppear(_ animated: Bool) {
// Adjust the height of the tableview
tableView.frame = CGRect(x: tableView.frame.origin.x, y: tableView.frame.origin.y, width: tableView.frame.size.width, height: tableView.contentSize.height)
// Add a border to the tableView
tableView.layer.borderWidth = 1
tableView.layer.borderColor = UIColor.black.cgColor
print("We ran ViewWillAppear")
}
// This function is used for adjusting the height of the tableview
override func viewDidLayoutSubviews(){
tableView.frame = CGRect(x: tableView.frame.origin.x, y: tableView.frame.origin.y, width: tableView.frame.size.width, height: tableView.contentSize.height)
tableView.reloadData()
}
// Allow cell deletion in tableview
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
// delete item at indexPath
self.items.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
self.tableViewHeightConstraint.constant = self.tableView.contentSize.height - 44
print(self.items)
print("Number of rows: \(tableView.numberOfRows(inSection: 0))")
}
delete.backgroundColor = UIColor.blue
return [delete]
}
In viewWillAppear , you can try
let limit:CGFloat = 900.0
if tableView.contentSize.height < limit {
tableView.frame = CGRect(x: tableView.frame.origin.x, y: tableView.frame.origin.y, width: tableView.frame.size.width, height: tableView.contentSize.height)
}
else {
tableView.frame = CGRect(x: tableView.frame.origin.x, y: tableView.frame.origin.y, width: tableView.frame.size.width, height: limit )
}
Or set value to
tableViewHeightConstraint.constant = ( tableView.contentSize.height < limit ) ? tableView.contentSize.height : limit
self.view.layoutIfNeeded()

ios seperatorView in tableView

I have added a seperator between cells to add spacing cell with separator
But when I change color of seperatorView to clearColor from blueColor it disappears,can someone help ?
Here's my code:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 50
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath)
cell.textLabel?.text = "Hello World"
cell.textLabel?.textColor = UIColor.blackColor()
cell.backgroundColor = UIColor.clearColor()
let additionalSeperatorThickness = CGFloat(6)
let additionalSeperator = UIView(frame: CGRectMake(0,
cell.frame.size.height - additionalSeperatorThickness,
cell.frame.size.width,
additionalSeperatorThickness))
additionalSeperator.backgroundColor = UIColor.clearColor()
cell.addSubview(additionalSeperator)
let imageView = UIImageView(image: UIImage(named: "text_box_1_converted.png")!)
cell.backgroundView = imageView
cell.bringSubviewToFront(additionalSeperator)
return cell
}

Resources