I'm working on a UITableView that acts like checklist. I have managed to display UITextLabel when UITableViewCell tapped and hide UITextLabel like (Checkmark) when UITableViewCell tapped again.
When I close the app it does display UITextLabel before tapped.
Took screenshots of the app:
Now I have some code that makes this work:
// 1
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for: indexPath)
let category = categories[indexPath.row]
// cell.secondTextLabelType = hide/display
if category.done {
cell.textLabel?.text = category.name
} else {
cell.textLabel?.text = ""
}
return cell
}
// 2
//hide and display the TextField2
func setItemStatus(item:Category) {
let status = item.done ? false : true
item.done = status
}
// 3
//MARK - TableView Delegate Methods
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//categories goes here
let item = categories[indexPath.row]
//cell?.twoItems = hide/display
setItemStatus(item: item)
tableView.reloadData()
saveCategories()
}
Related
I have a tableView with 2 custom xib cells. I want to switch the custom cell when user tapped it also adjust the cell height. How do I achieve it? I tried to use container view but then the height would be the same. I want to know if it is possible to do it with two xib for tableView cell? Thank you.
var isContactView: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(UINib(nibName: "ContactTableViewCell", bundle: nil), forCellReuseIdentifier: "contactCell")
tableView.register(UINib(nibName: "DetailTableViewCell", bundle: nil), forCellReuseIdentifier: "detailCell")
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//if ContactTableViewCell return 40
//if DetailTableViewCell return 150
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//by default the cell view is ContactTableViewCell.
//When user tapped the cell it will change to DetailTableViewCell.
if isContactView {
let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactTableViewCell
//do something...
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "detailCell", for: indexPath) as! DetailTableViewCell
//do something...
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//not sure how to change the xib in here.
//if cell view is ContactTableViewCell
cell view = tableView.dequeueReusableCell(withIdentifier: "detailCell", for: indexPath) as! DetailTableViewCell
isContactView = false
tableView.reloadData()
//else
cell view = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactTableViewCell
isContactView = true
tableView.reloadData()
}
There are 2 cases:
If there's just single cell to be viewed, then just put the following code in didSelect:
isContactView = !isContactView
tableView.reloadData()
If there are multiple cells in which the condition is to be applied. Please put a key in your data model.
For example:
testArr is the array of objects that you are displaying in tableview. Then keep a key, say isContactView in this model. And put the login based upon this key.
Like in case of cellForRow:
if testArr[indexpath.row].isContactView {
let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactTableViewCell
//do something...
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "detailCell", for: indexPath) as! DetailTableViewCell
//do something...
}
And in didselect:
isContactView = !testArr[indexPath.row].isContactView
How to show button Highlight colour,,and the colour is red
extension LeaveDetailVC: cellIndexCall{
func selectBtnIndex(sender: UIButton) {
let buttonPosition:CGPoint = sender.convert(.zero, to:leaveDetailTableView)
var indexPath = leaveDetailTableView.indexPathForRow(at: buttonPosition)
self.indexPath = indexPath!
print("\(String(describing: indexPath?.row))") /* index path of button
self.menuClickIndex = (indexPath?.row)!
}
}
And my Button is cover the tableViewCell.
And I also create a button delegate in cell class and call in viewController through extension.
I just want to highlight button and that is over cell.
override func tableView(_ tableView: UITableView, shouldHighlightRowAt
indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, didHighlightRowAt
indexPath:
IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell?.contentView.backgroundColor = UIColor.orange
cell?.backgroundColor = UIColor.orange
}
override func tableView(_ tableView: UITableView, didUnhighlightRowAt
indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell?.contentView.backgroundColor = UIColor.black
cell?.backgroundColor = UIColor.black
}
In your viewController
class LeaveDetailVC: ViewController {
var selectedRows: [IndexPath] = [] // i assume multiple select button
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_CELL") as! YOUR_CELL_CLASS
cell.isHighlight = selectedRows.indices.contains(indexPath) // Determine if cell was selected or not
}
}
extension LeaveDetailVC: cellIndexCall {
func selectBtnIndex(sender: UIButton) {
let buttonPosition:CGPoint = sender.convert(.zero, to:leaveDetailTableView)
var indexPath = leaveDetailTableView.indexPathForRow(at: buttonPosition)
if selectedRows.indices.contains(indexPath) {
if let index = selectedRows.index(of: indexPath) {
self.selectedRows.remove(at: index) // remove selected indexpath
}
} else {
self.selectedRows.append(indexPath) // add selected indexpath
}
}
}
In your cell class
var isHighlight: Bool = false
override func layoutSubviews() {
super.layoutSubviews()
// TODO : Set your button color based on isHighlight flag
}
I have a `tableView with three cells. In two of them I have a button. I would like to hide the button in the other cell, when one of the cells is tapped.
I have tried some solutions in didSelectRowAt but have not been able to hide the buttons:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 1 {
if let cell = tableView.cellForRow(at: indexPath) as? ComposeCell1 {
cell.compose.isHidden = true
if let cell2 = tableView.cellForRow(at: indexPath) as? ComposeCell2 {
cell2.compose.isHidden = true //I can reach the cell from here, but its not hiding the button
}
}
} else if indexPath.row == 2 {
if let cell = tableView.cellForRow(at: indexPath) as? ComposeCell2 {
cell.compose.isHidden = true
}
}
}
Try to track the index for the pressed button with a variable. And use the variable in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell to update the button's visibility. Only thing you need to do in didSelectRowAt is assign the index value the variable and reload the table view
var selectedIndex: Int?
....
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedIndex = indexPath.row
tableView.reloadData()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
.....
cell.compose.isHidden = indexPath.row != selectedIndex
.....
return cell
}
I am new in IOS and i am using swift.I want to change the text of label when height of cell expand.Please tell me how to change text when height expand of cell in swift.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{
var selectedIndex = -1
var height = 54
// Data model: These strings will be the data for the table view cells
let animals: [String] = ["Horse", "Cow", "Camel", "Sheep", "Goat"]
// cell reuse id (cells that scroll out of view can be reused)
let cellReuseIdentifier = "cell"
// don't forget to hook this up from the storyboard
#IBOutlet var tableView: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
// number of rows in table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 2
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
// create a new cell if needed or reuse an old one
let cell:Cell1 = self.tableView.dequeueReusableCell(withIdentifier: "cell") as! Cell1!
cell.textLabel?.text = "-"
return cell
}
// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell:Cell1 = self.tableView.dequeueReusableCell(withIdentifier: "cell") as! Cell1!
if(selectedIndex == indexPath.row)
{
height = 216
cell.textLabel?.text = "+"
}else{
height = 54
cell.textLabel?.text = "/"
}
return CGFloat(height)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
print("You tapped cell number \(indexPath.row).")
if(selectedIndex == indexPath.row)
{
selectedIndex = -1
}
else
{
selectedIndex = indexPath.row
}
}
}
In your code you are trying to dequeue the cell again in your heightForRowAt function, I think that's your issue.
so try replace your heightForRowAt function with the below code.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let cell = tableView.cellForRow(at: indexPath)
if(selectedIndex == indexPath.row)
{
height = 216
cell.textLabel?.text = "+"
}else{
height = 54
cell.textLabel?.text = "/"
}
return CGFloat(height)
}
below code supposed to call usernames from an array and user able to tap on the desired username. call to that array is a success and I can see the usernames but won't able to tap into it. and it don't even print "didSelectRowAt". appreciate your help. thanks.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! MentionUserCell
cell.username!.text = autoComplete[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return autoComplete.count
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let selectedCell: MentionUserCell = tableView.cellForRow(at: indexPath)! as! MentionUserCell
let selectedWord: String = selectedCell.username!.text! + " "
print("didSelectRowAt")
var string: NSString = NSString(string: self.commentTextView.text!)
string = string.replacingCharacters(in: otoCadang.sharedInstance.foundRange, with: selectedWord) as NSString
// change text field value
commentTextView.text = string as? String
// change cursor position
let positionOriginal = commentTextView.beginningOfDocument
if let cursorLocation: UITextPosition = self.commentTextView.position(from: positionOriginal, offset: otoCadang.sharedInstance.foundRange.location + selectedWord.characters.count)
{
self.commentTextView.selectedTextRange = self.commentTextView.textRange(from: cursorLocation, to: cursorLocation)
}
// remove suggestion
self.autoComplete.removeAll()
self.tableView.reloadData()
tableView.isHidden = true
}
Check List
tableview delegate is set properly
tableview selection mode == No Selection, then change to single selection
function name is correct func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
are you using any tap gesture on this view? remove it.
If you are editing UITextView will can't call to `didselectRowAt. Try to get the Your MentionUserCell, IndexPath in UITextView's methods and handle there. Example:
func textViewDidChange(_ textView: UITextView) {
var parentView = textView as UIView
while !(parentView is UITableViewCell) {
parentView = parentView.superview!
}
if let cell: MentionUserCell = parentView as? MentionUserCell {
if let indexPath = self.tableView.indexPath(for: cell) {
let yourIndexPath = indexPath
}
}
//your code
}
Hope it will help you.
When are using two or more cells the didSelectRow method is not working Well. You can use a button in cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifierName", for: indexPath) as! MentionUserCell
cell.username!.text = autoComplete[indexPath.row]
let button = cell.viewWithTag(101) as! UIButton
button.cellclick.addTarget(self, action: #selector(functionName(sender:)), for: .touchDown)
return cell
}
Now you get the indexPath:-
func functionName(sender:UIButton) {
let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.tableview)
let indexPath = self.tableview.indexPathForRow(at: buttonPosition)
print(indexPath.row)
}