I have a UITableView that gets its data from a sorted array. [A-Z].
How can I place a default cell to select at the top like this.
If a user doesn't want to click any of the other cells?
Here is my UITableViewCode below.
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.allowsSelection = true
tableView.allowsMultipleSelection = false
let groupedDictionary = Dictionary(grouping: nameArray, by: {String($0.prefix(1))})
// get the keys and sort them
let keys = groupedDictionary.keys.sorted()
// map the sorted keys to a struct
sections = keys.map{ Section(letter: $0, name: groupedDictionary[$0]!.sorted()) }
self.tableView.reloadData()
}
// MARK: - Table view data source
var selectedIndexPath = IndexPath()
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].names.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "HomeNames")
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeNames", for: indexPath)
let section = sections[indexPath.section]
if indexPath == selectedIndexPath {
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
} else {
cell.accessoryType = UITableViewCell.AccessoryType.none
}
cell.textLabel?.text = section.names[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let section = sections[indexPath.section]
selectedIndexPath = indexPath
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath)
tableView.register(UINib(nibName: "BBcell", bundle: nil), forCellReuseIdentifier: "Cell")
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
selectedHomeName = section.name[indexPath.row]
navigationItem.title = (selectedHomeName)
self.dismiss(animated: true, completion: nil)
}
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sections.map{$0.letter}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].letter
}
}
The simplest solution, in my opinion, would be to insert a new Section at the beginning of your sections variable after this line.
sections = keys.map{ Section(letter: $0, name: groupedDictionary[$0]!.sorted()) }
Something like:
sections.insert(Section(letter: "Default", ["All makes"]), at: 0)
I could have messed up the syntax a bit as I don't know your Section
Related
I have a tableView that allows users to make multiple selections from an array of data,
When the user clicks done, I would like the selected text to be then transferred over to another tableViews textView
Is there a way to transfer over the selected text and have the text separated by a , ?
I am coding programmatically.
var checked = [Int]()
var items = [String]()
var selectedItems = [String]()
#objc func done() {
let hud = JGProgressHUD(style: .dark)
hud.textLabel.text = "Saving!"
hud.show(in: view)
dismiss(animated: true, completion: nil)
hud.dismiss()
let aCell = aboutCell(style: .default, reuseIdentifier: nil)
aCell.textField3.text = selectedItems.joined(separator: ",")
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCell.AccessoryType.checkmark {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none
} else {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark
if selectedItems.contains(items[indexPath.row]) {
selectedItems.remove(at: selectedItems.firstIndex(of: items[indexPath.row])!)
} else {
selectedItems.append(items[indexPath.row])
}
checked.append(indexPath.row)
}
}
According to my understanding to the question, these are my thoughts:
1. First setup necessary variables
var items = [String]() // data to display in tableview
var selectedItems = [String]() // here all the selected datas are stored
2. Store the selected items data from the didSelectRowAt delegate method
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedItems.contains(items[indexPath.row]) { //check if the selected already contains the items and if contains remove it
selectedItems.remove(at: selectedItems.firstIndex(of: items[indexPath.row])!)
} else { // append the required items
selectedItems.append(items[indexPath.row])
}
// ..... other codes here
}
3. on done button
let requiredText = selectedItems.joined(separator: ",")
// pass this data through delegate method
There is no need to create an array for the selected items. You can simply call tableview method selectRow(at:animated:scrollPosition:) when selecting a row and when you need to get the selected rows just call tableview instance property indexPathsForSelectedRows. Then you just need to join the selected rows with a comma and use the resulting string in your textview or textfield. Don't forget to implement didDeselectRowAt item method as well to deselectRow.
import UIKit
class TableViewController: UITableViewController {
var items: [String] = ["1st", "2nd", "3rd", "4th", "5th"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.allowsMultipleSelection = true
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
}
}
func done() {
if let indexPaths = tableView.indexPathsForSelectedRows {
// note that this will preserve the order that the rows where selected. Just sort the indexPaths if you need it sorted.
let string = indexPaths.map { items[$0.row] }.joined(separator: ",")
print(string)
// your code
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCellID", for: indexPath) as! TableViewCell
cell.textLabel?.text = items[indexPath.row]
cell.accessoryType = cell.isSelected ? .checkmark : .none
return cell
}
}
I have attached the image click the card view expands the same card inside the table cell dynamically its passible to achieve this?
I have searched a lot but not working
Hear my code added header cell with CardView
added arrow button to click the button expand the cell
its able expand but not in parent card it was showing diff card
I have adde my source code
var hiddenSections = Set<Int>()
let tableViewData = [
["1","2","3","4","5"],
["1","2","3","4","5"],
["1","2","3","4","5"],
]
override func viewDidLoad() {
super.viewDidLoad()
let CustomeHeaderNib = UINib(nibName: "CustomSectionHeader", bundle: Bundle.main)
historyTableView.register(CustomeHeaderNib, forHeaderFooterViewReuseIdentifier: "customSectionHeader")
}
func numberOfSections(in tableView: UITableView) -> Int {
return self.tableViewData.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.hiddenSections.contains(section) {
return 0
}
return self.tableViewData[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = self.tableViewData[indexPath.section][indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return view.frame.width/4
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = self.historyTableView.dequeueReusableHeaderFooterView(withIdentifier: "customSectionHeader") as! CustomSectionHeader
header.setupCornerRadious()
let sectionButton = header.expandBtn
sectionButton?.setTitle(String(section),
for: .normal)
sectionButton?.tag = section
sectionButton?.addTarget(self,action: #selector(self.hideSection(sender:)), for: .touchUpInside)
return header
}
#objc
private func hideSection(sender: UIButton) {
let section = sender.tag
func indexPathsForSection() -> [IndexPath] {
var indexPaths = [IndexPath]()
for row in 0..<self.tableViewData[section].count {
indexPaths.append(IndexPath(row: row,
section: section))
}
return indexPaths
}
if self.hiddenSections.contains(section) {
self.hiddenSections.remove(section)
self.historyTableView.insertRows(at: indexPathsForSection(),
with: .fade)
} else {
self.hiddenSections.insert(section)
self.historyTableView.deleteRows(at: indexPathsForSection(),
with: .fade)
}
}
With out sections also you can achieve this. To do this,
1.Return cell height as section height. If user clicks on the cell then return total content height to the particular cell.
2.You need to take an array, if user selects cell, add indexPath number in to array. If selects already expand cell remove it from array. In height for row at index check indexPath is in array or not.
This is one of the way. With sections also you can do that.
//MARK:- UITableView Related Methods
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrDict.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
// var cel = tblExpandedTest.dequeueReusableCellWithIdentifier("expCell", forIndexPath: indexPath) as! CDTableViewCell
var cel : CaseHearingTabTVC! = tableView.dequeueReusableCell(withIdentifier: "caseHearingTabCell") as! CaseHearingTabTVC
if(cel == nil)
{
cel = Bundle.main.loadNibNamed("caseHearingTabCell", owner: self, options: nil)?[0] as! CaseHearingTabTVC;
}
//cell?.backgroundColor = UIColor.white
cel.delegate = self
if indexPath != selctedIndexPath{
cel.subview_desc.isHidden = true
cel.subview_remarks.isHidden = true
cel.lblHearingTime.isHidden = true
}
else {
cel.subview_desc.isHidden = false
cel.subview_remarks.isHidden = false
cel.lblHearingTime.isHidden = false
}
return cel
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectIndex = true;
if(selectedInd == indexPath.row) {
selectedInd = -1
}
else{
let currentCell = tableView.cellForRow(at: indexPath)! as! CaseHearingTabTVC
cellUpdatedHeight = Float(currentCell.lblHearingTime.frame.origin.y + currentCell.lblHearingTime.frame.size.height) + 2;
selectedInd = -1
tblCaseHearing.reloadData()
selectedInd = indexPath.row
}
let previousPth = selctedIndexPath
if indexPath == selctedIndexPath{
selctedIndexPath = nil
}else{
selctedIndexPath = indexPath
}
var indexPaths : Array<IndexPath> = []
if let previous = previousPth{
indexPaths = [previous]
}
if let current = selctedIndexPath{
indexPaths = [current]
}
if indexPaths.count>0{
tblCaseHearing.reloadRows(at: indexPaths, with: UITableView.RowAnimation.automatic)
}
}
func tableView(_ tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowIndexPath indexPath:IndexPath) {
(cell as! CaseHearingTabTVC).watchFrameChanges()
}
func tableView(_ tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowIndexPath indexPath:IndexPath) {
(cell as! CaseHearingTabTVC).ignoreFrameChanges()
}
func tableView(_ TableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
if indexPath == selctedIndexPath{
return CGFloat(cellUpdatedHeight)
}else{
return CaseHearingTabTVC.defaultHeight
}
}
Best approach is to create two different cells for normal card and expanded card.
fileprivate var selectedIndex: Int?
func registerTableViewCells() {
tableView.register(UINib(nibName:Nib.CardCell , bundle: nil), forCellReuseIdentifier: "CardCell")
tableView.register(UINib(nibName:Nib.ExpandedCardCell , bundle: nil), forCellReuseIdentifier: "ExpandedCardCell")
}
override func viewDidLoad() {
super.viewDidLoad()
self.registerTableViewCells()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let index = selectedIndex else {
return 115
}
if index == indexPath.row{
return 200
}
return 115
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let selected = selectedIndex, selected == indexPath.row{
let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandedCardCell", for: indexPath) as! ExpandedCardCell
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: "CardCell", for: indexPath) as! CardCell
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedIndex == indexPath.row{
selectedIndex = nil
}
else{
selectedIndex = indexPath.row
}
UIView.performWithoutAnimation {
tableView.reloadData()
}
}
TableView CheckMark Cell Value Removed After Scrolling Up It will Fix
TableView in You have face a problem many times to Checkmark after scroll Up then Scroll Down To show a Your Checkmark cell is will Removed Because cell is dequeueReusableCell So This Problem Fix , you Have just put Your code and Solved Your Problem.
Any More Help So Send Massage.
Thank you So much. :)
class ViewController: UIViewController , UITableViewDataSource , UITableViewDelegate{
var temp = [Int]()
var numarr = [Int]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numarr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "id")
cell = UITableViewCell.init(style: .default, reuseIdentifier: "id")
cell?.textLabel?.text = String(numarr[indexPath.row])
if temp.contains(numarr[indexPath.row] as Int)
{
cell?.accessoryType = .checkmark
}
else
{
cell?.accessoryType = .none
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
if temp.contains(numarr[indexPath.row] as Int)
{
cell?.accessoryType = .none
temp.remove(at: temp.index(of: numarr[indexPath.row])!)
}
else
{
cell?.accessoryType = .checkmark
temp.append(self.numarr[indexPath.row] as Int)
}
}
override func viewDidLoad() {
super.viewDidLoad()
for i in 1...100
{
numarr.append(i)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
I think if someone were to run your code it would not show any error. But with real data it probably will. The reason is the way you store your checkmarks. You store the data of a row into the temp array when you should be storing the actualy indexPath of the array so that only that row gets the checkmark. In your case, if a row has 1 inside it's label and you click on it, that cell will be highlighted. Now if you start scrolling and another cell contains 1 then that row will also be highlighted.
I have modified your example for the case of a single section. If there is more than one section, you need to store the indexPath instead of indexPath.row.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "id")
cell = UITableViewCell.init(style: .default, reuseIdentifier: "id")
cell?.textLabel?.text = String(numarr[indexPath.row])
if temp.contains(indexPath.row) {
cell?.accessoryType = .checkmark
} else {
cell?.accessoryType = .none
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
if temp.contains(indexPath.row) {
cell?.accessoryType = .none
temp.remove(at: indexPath.row)
} else {
cell?.accessoryType = .checkmark
temp.append(indexPath.row)
}
}
You are strongly discouraged from using a second array to keep the selected state.
This is Swift, an object oriented language. Use a custom struct for both num and the selected state.
In didSelectRowAt and didDeselectRowAt change the value of isSelected and reload the row.
And use always the dequeueReusableCell API which returns a non-optional cell.
struct Item {
let num : Int
var isSelected : Bool
}
var numarr = [Item]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numarr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "id", for: indexPath)
let item = numarr[indexPath.row]
cell.textLabel?.text = String(item)
cell.accessoryType = item.isSelected ? .checkmark : .none
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
updateSelection(at: indexPath, value : true)
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
updateSelection(at: indexPath, value : false)
}
func updateSelection(at indexPath: IndexPath, value : Bool) {
let item = numarr[indexPath.row]
item.isSelected = value
tableView.reloadRows(at: [indexPath], with: .none)
}
override func viewDidLoad() {
super.viewDidLoad()
(0...100).map{Item(num: $0, isSelected: false)}
}
I have a table view controller in my view controller. When I give it static number of rows and cell for row index method name it shows nothing to me in the table view. I have also reload the table view but it isn't showing I don't know why is it so,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell (style: .subtitle, reuseIdentifier: "cellID")
let message = messages[indexPath.row]
cell.textLabel?.text = message.text
return cell
}
Recheck if u have set
tableView.delegate = self
tableView.datasource = self
Also put a breakpoint on cellForRowAtIndexpath to check if code runs through the block.
Also Recheck the cellIdentifier (cellID) is correct or not.
class ViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {
//Getting the reference variables of storyboard
#IBOutlet weak var tableView:UITableView!
var messages = [String]()
override func viewDidLoad() {
super.viewDidLoad()
//Add some packages
messages.append("Super")
messages.append("Free ")
messages.append("Miscellaneous")
messages.append("All ")
tableView.datasource = self
tableView.delegate = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell (style: .subtitle, reuseIdentifier: "cellID")
let message = messages[indexPath.row]
cell.textLabel?.text = message.text
return cell
}
}
Use this . This one works for me
class yourViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var tableView:UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.datasource = self
tableView.delegate = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell=tableView.dequeueReusableCell(withIdentifier: "cellID",for : indexPath)
let message = messages[indexPath.row]
cell.textLabel?.text = message.text
return (cell)
}
}
I'm new to swift and working on a project in Swift 3.0 where I have a UITableView with three custom cells. In the first one I just have a image,button and a label. In the second one I have an image plus a label along with expandable and collapsible headers.Thus I have three different sections for this second cell. And lastly the third one is also contains just a label. In the first cell the UILabel is set underneath the image which contains a description about a person (constraints are been set). My requirement is only for the first cell dynamically adjust the cell size based on the size of the description. Help would much appreciate, the code as bellow.
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
print("Number of Sections: \(section)")
return arrayForTableView[section]
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let headerView : UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
headerView.contentView.backgroundColor = UIColor.yellow.withAlphaComponent(1.0)
}
func tapped(sender: UITapGestureRecognizer)
{
if let tag = sender.view?.tag{
expanedSections[tag] = !expanedSections[tag]
}
tableView.reloadData()
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UITableViewHeaderFooterView()
headerView.tag = section
let tapRecog = UITapGestureRecognizer(target: self, action: #selector(tapped))
tapRecog.numberOfTapsRequired = 1
tapRecog.numberOfTouchesRequired = 1
tapRecog.delegate = self
headerView.addGestureRecognizer(tapRecog)
return headerView
}
func numberOfSections(in tableView: UITableView) -> Int {
return arrayForTableView.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
return 1
case 1:
return expanedSections[section] ? getItemsForSection(self.tableData.freeGifts): 0
case 2:
return expanedSections[section] ? getItemsForSection(self.tableData.exclusiveOffers) : 0
case 3:
return expanedSections[section] ? getItemsForSection(self.tableData.allAudios) : 0
case 4:
return expanedSections[section] ? getItemsForSection(self.tableData.testamonials) : 0
default:
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// var cell: UITableViewCell?
print("Section : \(indexPath.section) : \(indexPath.row)")
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "HealerDetailsCell", for: indexPath) as! HealerDetailsTableViewCell
//cell.aboutLabel.preferredMaxLayoutWidth = (tableView.bounds)
cell.aboutLabel.sizeToFit()
populateHealerDetails.populateTable(cell, self.tableData.healerDetails)
return cell
case 1:
if tableData.freeGifts.count > 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "OffersCell",for: indexPath)
PopulateHealerDetailsAndOffers.populateTable(cell, self.tableData.freeGifts[indexPath.row] as! NSDictionary)
return cell
} else {
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "No Free Gifts At This Time"
return cell
}
case 2:
if tableData.exclusiveOffers.count > 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "OffersCell",for: indexPath)
PopulateHealerDetailsAndOffers.populateTable(cell, self.tableData.exclusiveOffers[indexPath.row] as! NSDictionary)
return cell
}else {
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "No Exclusive Offers At This Time"
return cell
}
case 3:
if tableData.allAudios.count > 0{
let cell = tableView.dequeueReusableCell(withIdentifier: "OffersCell",for: indexPath)
PopulateHealerDetailsAndOffers.populateTable(cell, self.tableData.allAudios[indexPath.row] as! NSDictionary)
return cell
}else{
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "NO Audios To Display"
return cell
}
case 4:
if tableData.testamonials.count > 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "TestamonialsCell", for: indexPath)
return cell
}else{
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "No Testamonials"
return cell
}
default:
let cell = tableView.dequeueReusableCell(withIdentifier: "TestamonialsCell", for: indexPath)
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//let indexPath = tableView.indexPathForSelectedRow!
//let currentCellValue = tableView.cellForRow(at: indexPath)! as UITableViewCell
}
1.Set the constraint of label.
2.Put numberOflines is equal to 0(Through storyboard or programmatically)
Add this code in viewDidLoad:
tableView.estimatedRowHeight = 300
tableView.rowHeight = UITableViewAutomaticDimension
Use this delegate method
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
For version >= iOS 8
override func viewDidLoad()
{
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0; // set to whatever your "average" cell height is
}
Steps to set constraints on storyboard:here
Important
If multiple lines labels, don't forget set the numberOfLines to 0.
Don't forget label.preferredMaxLayoutWidth =
CGRectGetWidth(tableView.bounds)
I think you want to expand/elapse UITableViewCell depending on the data each cell would have at runtime. I suppose, you already have implemented all of the first aid options regarding UITableView in swift.
Please try this method, which will always be called when your each cell is loaded.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
//CellAnimator.animateCell(cell: cell, withTransform: CellAnimator.TransformWave, andDuration: 1)
//This commented line possibly might not be your requirement.
//But this is actually used to animate cell while loading.
//You can try some constraints or cell height related stuff here which would definitely work for each cell differently.
//Try calling cell specific loads either.
tableView.scrollToRow(at: indexPath as IndexPath, at: .none, animated: true)
/*let indexPath = IndexPath(item: (selectedCellIndexPath?.row)!, section: 0)
tableView.reloadRows(at: [indexPath], with: .none)
checkTrue = true
*/
}
Please check out this:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var tableViewDataSource = ["fewhf wfh wf wfw h dfw \n\n wufhw f ewfw wf w \n\n f wefe wfef w","fewhf wfh wf wfw h dfw \n\n wufhw f ewfw wf w \n\n f wefe wfef w",
"fewhf wfh wf wfw h dfw \n\n wufhw f ewfw wf w \n\n f wefe wfef w",
"fewhf wfh wf wfw h dfw \n\n wufhw f ewfw wf w \n\n f wefe wfef w"
]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView.delegate = self
tableView.dataSource = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//Tableview
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableViewDataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellHere") as! TableViewCellHere
cell.cellHere.text = tableViewDataSource[indexPath.row]
cell.cellHere.textAlignment = .justified
return cell
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0 || indexPath.row == 1
{
return 120.0
}
else
{
return 50.0
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0 || indexPath.row == 1
{
return 120.0
}
else
{
return 50.0
}
}
}
This is working for me like this:
enter image description here