I have one custom style UITableviewCell and it have default height for other I am using tableview cell with style of subtitle and I want to make subtitle to be multiple lines. And it's doing good but having problem with calculating tableview cell height and I use UITableviewAutomaticDimension but its not working.
Here is my code
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if(indexPath.row==0){
var cell: ImageCell! = tableView.dequeueReusableCellWithIdentifier("ImageCell") as? ImageCell
if cell == nil {
tableView.registerNib(UINib(nibName: "ImageCell" ,bundle: nil), forCellReuseIdentifier: "ImageCell")
cell = tableView.dequeueReusableCellWithIdentifier("ImageCell") as? ImageCell
}
return cell
}else{
var cell: UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("SubtitleCell")
if (cell == nil) {
cell = UITableViewCell.init(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "SubtitleCell")
cell!.backgroundColor = UIColor.brownColor()
cell!.textLabel?.font = UIFont.init(name: "HelveticaNeue", size: 15)
cell!.textLabel?.textColor = UIColor.blackColor()
cell!.textLabel?.highlightedTextColor = UIColor.lightGrayColor()
cell!.selectedBackgroundView = UIView.init()
}
cell!.textLabel?.text = "TExt"
cell!.detailTextLabel!.text="Keep in mind that UITableView is defined as an optional in the function, which means your initial cell declaration needs to check for the optional in the property. Also, the returned queued cell is also optional, so ensure you make an optional cast to UITableViewCell. Afterwards, we can force unwrap because we know we have a cell."
allowMultipleLines(cell!)
cell!.imageView?.image = UIImage(named: "IconProfile")
return cell!
}
}
func allowMultipleLines(tableViewCell:UITableViewCell) {
tableViewCell.detailTextLabel?.numberOfLines = 0
tableViewCell.detailTextLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(indexPath.row==0){
return 172
}else{
return UITableViewAutomaticDimension
}
}
in your viewDidLoad() Method you need to write
yourTableViewName.rowHeight = UITableViewAutomaticDimension
And Add One more method
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(indexPath.row==0){
return 172
}else{
return UITableViewAutomaticDimension;
}
}
i hope this will help you
Related
When I selected a row, text color turns white. however, when I scroll to refresh the row, the text color turns back to black. so I have added a logic if(cell.selected). However it didn't work. when I scroll. the code can't get into if case.Here is the code :-
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell:UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
for subview in selectedCell.subviews {
if let view = subview as? UILabel {
view.textColor = UIColor.whiteColor()
}
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var renderWidth:CGFloat = 8
var renderYPosition:CGFloat = 15
let cell:UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "idcell")
let date = UILabel(frame: CGRectMake(renderWidth, renderYPosition, 110, 20))
let dateText = "asdasdsad"
date.text = dateText
if (cell.selected) {
date.textColor = UIColor.whiteColor()
}
cell.addSubview(date)
}
You are creating a new UITableViewCell everytime. It is recommended to reuse it.
Instead of creating a new cell with this:
let cell:UITableViewCell=UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "idcell")
Use this to reuse the cell:
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdInStoryboard", forIndexPath: indexPath) as! UITableViewCell
The identifier should be the same as the one you set in storyboard.
The problem is with your if clause in cellForRowAtIndexPath function and also you create cell instance everytime you load the tableview.You need to reuse tableview cells.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var renderWidth:CGFloat = 8
var renderYPosition:CGFloat = 15
let cell = tableView.dequeueReusableCellWithIdentifier("idcell", forIndexPath: indexPath) as! YourTableViewCell
let date = UILabel(frame: CGRectMake(renderWidth, renderYPosition, 110, 20))
let dateText = "asdasdsad"
date.text = dateText
if (cell.selected) {
date.textColor = UIColor.whiteColor()
} else {
date.textColor = UIColor.blackColor() // You didn't add else
}
cell.addSubview(date)
}
I am using a popover tableview in my project. I want to change the tableview cell's text colour from grey to red on selection. And i also want the highlighted color to remain red when the popover tableview is loaded next time like left menu selection. Need help to do this. I have provided the code for the popover tableview.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if tableView === tableViewPopOver {
let cell = UITableViewCell(style: .Default, reuseIdentifier: nil)
cell.textLabel?.text = FeedFilter.allValues[indexPath.row].rawValue
if indexSelected == indexPath.row {
cell.textLabel?.textColor = UIColor.redColor()
} else {
cell.textLabel?.textColor = UIColor.lightGrayColor()
}
//cell.selectionStyle = .None
return cell
}
let cell = tableView.dequeueReusableCellWithIdentifier(kDreamFeedTableViewCell, forIndexPath: indexPath) as! DreamFeedTableViewCell
cell.selectionStyle = .None
let dream = self.arrayDreams[indexPath.row]
cell.dream = dream
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if tableView === tableViewPopOver {
//tableViewPopOver?.cellForRowAtIndexPath(indexPath)?.textLabel?.highlightedTextColor = UIColor.redColor()
//selectedIndexPath = indexPath.row
let cell = tableView.cellForRowAtIndexPath(NSIndexPath.init(forRow: indexSelected, inSection: 0))
cell?.textLabel?.textColor = UIColor.lightGrayColor()
let cell2 = tableView.cellForRowAtIndexPath(indexPath)
cell2?.textLabel?.textColor = UIColor.redColor()
tableView.deselectRowAtIndexPath(indexPath, animated: true)
indexSelected = indexPath.row
self.popover.dismiss()
NRLoader.showLoader()
self.searchDreams(true)
}
else { // dream feed tableview
tableView .deselectRowAtIndexPath(indexPath, animated: false)
let dream = self.arrayDreams[indexPath.row]
if !isValidUser(dream.user) {
return
}
if isCurrentUser(dream.user)
{
self.pushToUserDreamViewControllerForDream(dream)
}
else
{
tableView .deselectRowAtIndexPath(indexPath, animated: false)
self.pushToFeedDetailViewControllerForDream(dream)
}
}
}
I see a problem with your code relate to tableViewPopOver. If you set selection style is .None. You can't select cell.
With your problem I can suggest for you two way to resolve:
If you want use cell.textLabel?.highlightedTextColor you will have face a problem: background of cell will be grey or blue depend on style selection you select. If you can accept it. You can implement like this:
You create a variable to hold a cell selected. Maybe it is int value like var indexSelected = 3. And when you implement cellForRowAtIndexPath you should implement like this:
cell.textLabel?.text = FeedFilter.allValues[indexPath.row].rawValue
cell.textLabel?.highlightedTextColor = UIColor.redColor()
if indexPath.row == indexSelected {
tableView.selectRowAtIndexPath(indexPath, animated:true, scrollPosition: .None)
}
return cell
And in didSelectRowAtIndexPath you update indexSelected:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
indexSelected = indexPath.row //update selected row
}
If you don't want cell background change color. You can choose this way. You should create variable like the way above. But in cellForRowAtIndexPath you should implement:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")//init cell it depend on your way create cell
cell?.textLabel?.text = "Your text"
if indexSelected == indexPath.row {
cell?.textLabel?.textColor = UIColor.redColor()
} else {
cell?.textLabel?.textColor = UIColor.lightGrayColor()
}
return cell!
}
and in didSelectCellAtIndexPath you should implement:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(NSIndexPath.init(forRow: indexSelected, inSection: 0))
cell?.textLabel?.textColor = UIColor.lightGrayColor()
let cell2 = tableView.cellForRowAtIndexPath(indexPath)
cell2?.textLabel?.textColor = UIColor.redColor()
tableView.deselectRowAtIndexPath(indexPath, animated: true)
indexSelected = indexPath.row //update selected row
}
Here Demo: Demo
Hope this help!
To change cell's text colour to red on selection you need to implement didSelectRowAtIndexPath and change the cell text Color to red, but it will not stay red when you open it the next time. to handle that you need to have a member variable selectedIndexPath. So it will be something like this
var selectedIndexPath:NSIndexPath!
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.textLabel?.highlightedTextColor = UIColor.redColor()
selectedIndexPath = indexPath
}
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
cell.textLabel?.highlightedTextColor = UIColor.grayColor()
selectedIndexPath = nil
}
}
And to load the table next time with the selected cell red text colour you need to add this line in your cellForRowAtIndexPath
Cell
cell.textLabel?.highlightedTextColor = indexPath == selectedIndexPath ? UIColor.redColor() : UIColor.grayColor()
}
Any idea on how I can manage to do the use case I have below. Although I manage to do this using UITableView, I still get some issue every time I scroll the table view.
Scenario: The table view needs to adjust the height of the cell dynamically based on which item is selected. Each item would have different options inside of it. When Options is selected it should be able to show the options under the item and automatically adjust the height.
Solution: I subclassed UITableView and UITableViewCell. Every time Options is selected/tapped I will call beginUpdate and endUpdate which is working perfectly.
Problem: Every time the user scrolls down the options are not showing correctly.
Everytime when you scrolls up or down the uitableview will call the cellForRowAtIndexPath and the tableView will reload.
So in this case you need to track down the cell which is selected before scrolling up or down and after scrolling you just need to replace the states (e.g. heights) with that desired cell.
In my case I am using some veriable to keep track of the hegiht of the cell.
Here is my code below : -
import UIKit
class WaitingListClass: UIViewController,UITableViewDataSource, UITableViewDelegate {
var selectedCellIndexPath: NSIndexPath!
let SelectedCellHeight: CGFloat = 88.0
let UnselectedCellHeight: CGFloat = 44.0
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
let appdelegateObjForThisClass = UIApplication.sharedApplication().delegate as! AppDelegate
tableView.delegate = self
tableView.dataSource = self
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.backgroundColor = UIColor.clearColor()
self.tableView.separatorColor = tableViewSeperatorColor
self.tableView.tableFooterView = UIView(frame: CGRectZero)
self.tableView.contentInset = UIEdgeInsetsZero
}
internal func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if noDataForTable == true{
return 1
}
return appdelegateObjForThisClass.nameDataForTable.count
}
internal func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cellIdentifier = "WaitingCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! CellClassWaitingList
cell.nameDisplayLbl.text = appdelegateObjForThisClass.nameDataForTable[indexPath.row]["name"]!
cell.backgroundColor = tableViewCellColor
cell.nameDisplayLbl.textColor = UIColor(red: 191/255, green: 193/255, blue: 192/255, alpha: 1)
cell.idDisplayLbl.textColor = UIColor(red: 48/255, green: 143/255, blue: 94/255, alpha: 1)
cell.idDisplayLbl.text = appdelegateObjForThisClass.indexForTable[indexPath.row]
cell.userInteractionEnabled = true
cell.clipsToBounds = true
cell.selectionStyle = UITableViewCellSelectionStyle.None
let heightOfCell : CGFloat = self.tableView.delegate!.tableView!(self.tableView, heightForRowAtIndexPath: indexPath)
if heightOfCell == self.UnselectedCellHeight{
cell.stackOfBtnInCell.hidden = true
}else if heightOfCell == self.SelectedCellHeight{
cell.stackOfBtnInCell.hidden = false
}
return cell
}
internal func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CellClassWaitingList
if let selectedCellIndexPath = selectedCellIndexPath {
if selectedCellIndexPath == indexPath {
self.selectedCellIndexPath = nil
UIView.animateWithDuration(0.5, animations: {
cell.stackOfBtnInCell.hidden = true
self.view.layoutIfNeeded()
})
} else {
UIView.animateWithDuration(0.5, animations: {
cell.stackOfBtnInCell.hidden = false
self.view.layoutIfNeeded()
})
self.selectedCellIndexPath = indexPath
}
} else {
UIView.animateWithDuration(0.5, animations: {
cell.stackOfBtnInCell.hidden = false
self.view.layoutIfNeeded()
})
selectedCellIndexPath = indexPath
}
tableView.beginUpdates()
tableView.endUpdates()
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CellClassWaitingList
cell.stackOfBtnInCell.hidden = true
}
// MARK: - Cell Separator Setting to Full Size
internal func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if(self.tableView.respondsToSelector(Selector("setSeparatorInset:"))){
self.tableView.separatorInset = UIEdgeInsetsZero
}
if(self.tableView.respondsToSelector(Selector("setLayoutMargins:"))){
self.tableView.layoutMargins = UIEdgeInsetsZero
}
if(cell.respondsToSelector(Selector("setLayoutMargins:"))){
cell.layoutMargins = UIEdgeInsetsZero
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if let selectedCellIndexPath = selectedCellIndexPath {
if selectedCellIndexPath == indexPath {
return SelectedCellHeight
}
}
return UnselectedCellHeight
}
}
Now what I am doing here is taking a variable called selectedCellIndexPath which will take the selected cell's indexpath first. Next I am taking two more variable called SelectedCellHeight and UnselectedCellHeight which generally stores some height value to interchange each other for the cell in some cases like -
When tableview will be scrolled.
When cell will be selected and deselected.
For rest of the implementation try to look over the tableView datasource and delegate methods.
Thank you,
Hope this helped.
you need to keep a list of your cell states and in your table view data source cellAtIndexPath: and heightForCellAtIndexPath: you should respectively format your cell and specify the desired cell height.
You could create an NSMutableSet and add/remove NSIndexPath objects to it, or use an NSMutableDictionary and check whether a certain key corresponding to a cell's index has a value.
what do you mean "the options are not showing correctly"?
Also, how I would do it:
Create another UITableViewCell in the UITableView via the Storyboard. That TableView cell has the custom height you need.
Create a new UITableViewCell class file.
Assign the new class to the cell in the storyboard.
Call TableView.reloadData() when Options is pressed. And turn a Bool to true for the selected cell.
In the cellForRowAtIndexPath() use the custom UITableViewCell class when the Bool is on true.
I have an MGSwipeTableCell added in my tableView like this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let reuseIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! MGSwipeTableCell!
if cell == nil {
cell = MGSwipeTableCell(style: UITableViewCellStyle.Default, reuseIdentifier: reuseIdentifier)
}
cell.delegate = self
cell.backgroundColor = blue
}
All works fine. But now If I tap the cell the color of the cell changes for maybe a second to white and then to green (default color is blue). This is what should happen if the cell has been pressed:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let mySelectedCell = tableView.cellForRowAtIndexPath(indexPath) as! MGSwipeTableCell!
mySelectedCell.backgroundColor = green
mySelectedCell.detailTextLabel?.text = "Test"
}
So the color should only change to green not to white and then to green and a detailTextLabel with the text "Test" should be displayed.
I hope you can help me to solve this problem. I don't really know what to do.
Solution:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let reuseIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! MGSwipeTableCell!
cell = MGSwipeTableCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
cell.selectionStyle = UITableViewCellSelectionStyle.None
cell.delegate = self
cell.backgroundColor = blue
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let reuseIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! MGSwipeTableCell!
if cell == nil {
//Change this line
cell = MGSwipeTableCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: reuseIdentifier)
}
//And this line
cell.selectionStyle = UITableViewCellSelectionStyle.None
cell.delegate = self
cell.backgroundColor = blue
}
leave everything as is inside "didSelectRowAtIndexPath"
I've been trying to get a UISwitch shown as an accessory view in my UITableViewCell, but it just won't show up. I think there might be something I'm overseeing.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = self.tableView.dequeueReusableCellWithIdentifier("enabledCell") as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "enabledCell")
}
cell!.textLabel?.text = "Alarm enabled"
var enabledSwitch = UISwitch(frame: CGRectZero) as UISwitch
enabledSwitch.on = true
cell!.accessoryView = enabledSwitch
return cell!
}