I set up my tableView and has two springVar as shown in the image below. I want my tableview to show empty cells after the two springVar so that my solve bar is at the bottom of the screen. Any advices on how to go about it? My code is below.
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return springVar.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value2, reuseIdentifier: cellIdentifier)
}
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")
var data : NSManagedObject = springVar[indexPath.row] as! NSManagedObject
cell!.textLabel!.text = "Spring \(indexPath.row + 1)"
var force : Float = data.valueForKey("force") as! Float
var stiffness : Float = data.valueForKey("stiffness") as! Float
cell!.detailTextLabel!.text = "Force =\(force) \t Stiffness =\(stiffness)"
cell!.detailTextLabel!.textColor = UIColor .darkGrayColor()
return cell!
}
i think this maybe helpfull
if indexPAth.row / 2 == 0
{
return UITableViewCell()
// u can customize ur cell to show a button or anything else
}
this show a custom/blank cell after each 2 cell,(odd)
You can add Footer view in your tableView this way:
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerView = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40))
footerView.backgroundColor = UIColor.whiteColor()
//add button in your footer view
var button = UIButton(frame: CGRectMake(0, 0, 75, 30))
button.setTitle("Solve", forState: UIControlState.Normal)
button.setTitleColor(UIColor.brownColor(), forState: UIControlState.Normal)
button.addTarget(self, action: "buttonTapAction:", forControlEvents: UIControlEvents.TouchUpInside)
footerView.addSubview(button)
return footerView
}
override func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 40.0
}
And your result will be:
You can adjust the footerHeight according to your own needs.
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footerHeight : CGFloat = (tableView.frame.size.height - (CGFloat(springVar.count) * 45.0) - 45.0 - 64.0)
let oneCell = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: footerHeight))
return oneCell
}
override func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
let footerHeight : CGFloat = (tableView.frame.size.height - (CGFloat(springVar.count) * 45.0) - 45.0 - 64.0)
return footerHeight
}
Related
I have an expandable and collapsible section in my tableview cell for days of the week. When you click the open button to expand the section the button changes state to close and you can click it again to collapse. However, if you open multiple sections and start scrolling in the tableview those sections close and open but the button state does not change back to close once all the sections have reopened from scrolling.
I was doing some research and it seems like the state is not being saved. Is there any way of saving the state of those buttons using dequeuereusableheaderfooterview() in the viewForHeaderInSection? Or does it have to be done in the cellForRowAt function?
var barDeals: [ExpandableDealsStruct] = []
#IBOutlet weak var daysTable: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
daysTable.dataSource = self
daysTable.delegate = self
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let view = UIView()
view.backgroundColor = .black
let headerLabel = UILabel()
let button = UIButton(type: .system)
let headerList = DaysService.instance.getHeader()
headerLabel.textColor = .white
headerLabel.font = UIFont.boldSystemFont(ofSize: 20)
headerLabel.text = headerList[section]
button.setTitle("Open", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
button.addTarget(self, action: #selector(handleOpenClose), for: .touchUpInside)
button.tag = section
headerLabel.frame = CGRect(x: 5, y: 7.5, width: 150, height: 25)
button.frame = CGRect(x: 150, y: 7.5, width: 150, height: 25)
view.addSubview(headerLabel)
view.addSubview(button)
return view
}
#objc func handleOpenClose(button: UIButton)
{
let section = button.tag
self.daysTable.beginUpdates()
var indexPaths = [IndexPath]()
for deals in self.barDeals[section].deals.indices
{
let indexPath = IndexPath(row: deals, section: section)
indexPaths.append(indexPath)
}
let isExpanded = self.barDeals[section].isExpanded
self.barDeals[section].isExpanded = !isExpanded
button.setTitle(!isExpanded ? "Close" : "Open", for: .normal)
if isExpanded
{
daysTable.deleteRows(at: indexPaths, with: .fade)
}
else
{
daysTable.insertRows(at: indexPaths, with: .fade)
}
self.daysTable.endUpdates()
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
{
return 1
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
return 40
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if self.barDeals[section].isExpanded == false
{
return 0
}
return self.barDeals[section].deals.count
}
func numberOfSections(in tableView: UITableView) -> Int
{
return self.barDeals.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "DaysCell", for: indexPath)
let deals = self.barDeals[indexPath.section].deals[indexPath.row]
cell.textLabel?.text = deals
return cell
}
}
I have a UITableViewController, which has a custom cell that I want to display an image and labels. screenshots can explain my problem very well, it looks like this
.
And when I select any cell it looks like
In tableviewcontroller cell is not visible in proper shape according to constraints
here is my custom cell with autolayout constraints
How I can fix this issue? ... I created this tableviewcontroller programmatically without using storyboard.
here is code sample of data source and delegates of tableviewcontroller
override func numberOfSections(in tableView: UITableView) -> Int {
var numOfSections: Int = 0
let count = conversations.count
if count > 0 {
// tableView.separatorStyle = .none
numOfSections = 1
tableView.backgroundView = nil
}
else
{
let frame = CGRect(x: 0,
y: 0,
width: tableView.bounds.size.width,
height: tableView.bounds.size.height)
let noDataLabel: UILabel = UILabel(frame: frame)
noDataLabel.text = "You don't have any messages. 🙃"
noDataLabel.textColor = UIColor.black
noDataLabel.textAlignment = .center
tableView.backgroundView = noDataLabel
tableView.separatorStyle = .none
}
return numOfSections
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return conversations.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "inboxCell", for: indexPath) as! InboxCell
cell.conversation = conversations[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let uids = conversations[indexPath.row].conversationUseruids
for uid in uids{
if uid == Account.account.user.uid{
}
else{
User.getUser(with: uid, completion: { (user) in
self.selectedUser.append(user!)
})
}
}
tableView.deselectRow(at: indexPath, animated: true)
let index = indexPath.row as Int
messageVC.conversationIndex = index
messageVC.conversation = self.conversations[index]
navigationController?.pushViewController(messageVC, animated: true)
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
it happen because your image not have upper lower constraint if not working than let me know
I am implementing a swipe to delete feature on all UITableViewCell in my UITableView. In the same time I would like use a custom button, and for this purpose, this tutorial came in handy: Custom edit view in UITableViewCell while swipe left. Objective-C or Swift
(I went with the 4th solution). So far, I am satisfied with my overall result as it work out just well. However, I have noticed that in my case, when swiping on the cell, the cell travel does not stop just after the hidden button is unveiled, rather is continues and it unveils some gray space. Once the cell is released, it bounces back, covering the gray space. The big question is, how do I disable this bounce effect and have the cell stop on slide just after the button is unveiled?
My problem is very similar to this one How to remove UITableViewCell swipe to delete bounce
. However, I've tried all UISwipeViewDelegate solutions and none of them work for me.
What I need it to be like:
What it's actually like:
This is my code:
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var tableView: UITableView!
lazy var rowHeight: CGFloat = {
return 82
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
let nibName = UINib(nibName: "TableViewCell", bundle: nil)
tableView.register(nibName, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return 20
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
cell.makeCellWith(image: "sampleImage", userName: "userNameSample")
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return rowHeight
}
// MARK: - Cell Sections
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
view.frame = UIEdgeInsetsInsetRect(view.frame, UIEdgeInsetsMake(0, 10, 0, 10))
}
// Set the spacing between sections
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 10
}
// Make the background color show through
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.clear
return headerView
}
// MARK: - Slide to delete feature
fileprivate func whitespaceString(font: UIFont = UIFont.systemFont(ofSize: 15), width: CGFloat) -> String {
let padding: CGFloat = 20
let mutable = NSMutableString(string: "")
let attribute = [NSAttributedStringKey.font: font]
while mutable.size(withAttributes: attribute).width < width - (2 * padding) {
mutable.append(" ")
}
return mutable as String
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let whitespace = whitespaceString(width: rowHeight)
let deleteAction = UITableViewRowAction(style: .default, title: whitespace) { (action, indexPath) in
// do action on delete here
}
// create a color from pattern image and set the color as a background color of action
let view = UIView(frame: CGRect(x: 0, y: 0, width: rowHeight, height: rowHeight))
view.backgroundColor = UIColor.white
let imageSize: CGFloat = 50
let imageView: UIImageView = {
let iv = UIImageView()
let buttonImage = UIImage(named: "plusButton")
iv.image = buttonImage
return iv
}()
imageView.frame = CGRect(x: (view.frame.height - imageSize)/2,
y: (view.frame.width - imageSize)/2,
width: imageSize,
height: imageSize)
view.addSubview(imageView)
let image = view.image()
deleteAction.backgroundColor = UIColor(patternImage: image)
return [deleteAction]
}
// MARK: - Delete Object
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
fileprivate extension UIView {
func image() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
guard let context = UIGraphicsGetCurrentContext() else {
return UIImage()
}
layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
I am using a table view with multiple section. In one table view cell which is having text label and detailed text label to display array objects. Now I want add a new section, in this section I will be having more text like a paragraph. How to display data in text view?
{
var dataSection01:NSMutableArray = NSMutableArray()
var dataSection02:NSMutableArray = NSMutableArray()
var sectionTitleArray : NSMutableArray = NSMutableArray()
var arrayForBool : NSMutableArray = NSMutableArray()
var sectionContentDict : NSMutableDictionary = NSMutableDictionary()
in viewDidLoad()
sectionTitleArray = ["Assignment Information","Details"]
let tmp1 : NSArray = assignInfoArray
var string1 = sectionTitleArray .objectAtIndex(0) as? String
[sectionContentDict .setValue(tmp1, forKey:string1! )]
let tmp2 : NSArray = detailsInfoArray
string1 = sectionTitleArray .objectAtIndex(1) as? String
[sectionContentDict .setValue(tmp2, forKey:string1! )]
dataSection01 = [ "Name:", "Phone", "Email" so on]
dataSection02 = [ "Address", "Street", "State","ZipCode"]
//mapping like this using object mapper
assignInfoArray.addObject((newDetails?.clientName)!)
assignInfoArray.addObject((newDetails?.clientPhone)!)
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sectionTitleArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let CellIdentifier = "CellRightDetail"
var cell :UITableViewCell?
cell = self.tableView.dequeueReusableCellWithIdentifier(CellIdentifier)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value2, reuseIdentifier: "CellRightDetail")
}
let manyCells : Bool = arrayForBool .objectAtIndex(indexPath.section).boolValue
if (!manyCells) {
// cell.textLabel.text = #"click to enlarge";
}
else{
let items: NSMutableArray = self.dataFromIndexPath(indexPath)
let content = sectionContentDict .valueForKey(sectionTitleArray.objectAtIndex(indexPath.section) as! String) as! NSArray
cell!.detailTextLabel?.text = content .objectAtIndex(indexPath.row) as? String
cell!.detailTextLabel?.textColor = UIColor.whiteColor()
cell!.textLabel?.textColor = UIColor.whiteColor()
cell!.textLabel?.font = UIFont(name:"Helvetica-Bold", size: 13.0)
cell!.textLabel?.text = items[indexPath.row] as? String
}
return cell!
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
if(arrayForBool .objectAtIndex(section).boolValue == true)
{
let tps = sectionTitleArray.objectAtIndex(section) as! String
let count1 = (sectionContentDict.valueForKey(tps)) as! NSArray
return count1.count
}
return 0;
}
func dataFromIndexPath(indexPath: NSIndexPath!) -> NSMutableArray!
{
if (indexPath.section == 0)
{
return dataSection01
}
else if (indexPath.section == 1)
{
return dataSection02
}
return nil
}
}
In storyboard
Blue color is the first cell and green color is my second cell.
You have to create two cell like this and for each cell you have to create different customcell class. Make outlets of UILabel and UITextView in their respective class and use the below code .
May be your requirement vary little bit, so use delegates according to it.
Implement your code like this:
// MARK:- --- TableView Height ---
open func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat{
return 45
}
open func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat{
return 1
}
open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 45
}
open func numberOfSections(in tableView: UITableView) -> Int{
return 2
}
// MARK:- --- TableView tittle ---
open func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
return "hearder " + String(section)
}
open func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?{
let viewHeader : UIView = UIView(frame: CGRect(x: 0 , y: 64, width: self.view.frame.size.width , height: 45))
viewHeader.backgroundColor = UIColor(red: 180.0/255.0, green: 160.0/255.0, blue: 240.0/255.0, alpha: 1)
let btnHeader : UIButton = UIButton(frame: CGRect(x: 0 , y: 0, width: viewHeader.frame.size.width , height: viewHeader.frame.size.height))
btnHeader.setTitle("section #\(section)", for: UIControlState())
btnHeader.backgroundColor = UIColor.darkGray
btnHeader.isSelected = arrIsExpand[section]
btnHeader.tag = section
btnHeader.addTarget(self, action:#selector(expandMethod(_:)) , for: UIControlEvents.touchUpInside)
viewHeader.addSubview(btnHeader)
return viewHeader
}
// MARK:- --- TableView data source ---
open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return 10
}
open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
if(indexPath.section == 0){ // for your first section
let firstCell : MyFirstCustomCell = tableView.dequeueReusableCell(withIdentifier: "firstcell") as! DesignTableCell
firstCell.lblTittle?.text = "Tittle"
firstCell.lblDescription?.text = "Description"
return firstCell
}
//for second section
else{
let secondCell : MySecondCustomCell = tableView.dequeueReusableCell(withIdentifier: "secondcell") as! DesignTableCell
secondCell.lblTittle?.text = "Tittle"
secondCell.txtViewData?.text = "Blah! Blah!"
return secondCell
}
}
May be you face the problem with the row height because I give static height here i.e. 45, so use uiautomaticdimension instead of static 45, and also impliment the delegate estimatedHeightForRow.
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{
var tableView:UITableView!
var city = ["gz","dl","sz","bj","hz"]
var city2 = ["gd","ln","gx","he","se"]
var city3 = ["a","b","c","d","e"]
let cellid = "reusecell"
let mycellid = "customer"
override func viewDidLoad()
{
super.viewDidLoad()
tableView = UITableView(frame: CGRect(x: 0, y: 20, width: self.view.frame.width, height: self.view.frame.height), style: UITableViewStyle.Grouped)
tableView.dataSource = self
tableView.delegate = self
self.view.addSubview(tableView)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if section == 0
{
return city.count
}else if section == 1
{
return city2.count
}
else
{ print("section3 count")
return city3.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
if indexPath.section == 0
{
var cell = tableView.dequeueReusableCellWithIdentifier(cellid)
if cell == nil
{
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellid)
}
cell?.textLabel?.text = "\(city[indexPath.row])"
cell?.detailTextLabel?.text = "beautiful place"
cell?.imageView?.image = UIImage(named: "test.png")
cell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
cell?.selectionStyle = UITableViewCellSelectionStyle.Gray
tableView.beginUpdates()
return cell!
}
else if indexPath.section == 1
{
var cell = tableView.dequeueReusableCellWithIdentifier(cellid)
if cell == nil
{
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellid)
}
cell?.textLabel?.text = "\(city2[indexPath.row])"
cell?.detailTextLabel?.text = "beautiful place"
cell?.imageView?.image = UIImage(named: "test.png")
cell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
cell?.selectionStyle = UITableViewCellSelectionStyle.Gray
tableView.beginUpdates()
return cell!
}
else
{
var mycell:MyCellTableViewCell? = tableView.dequeueReusableCellWithIdentifier(mycellid) as? MyCellTableViewCell
if mycell == nil
{
print("section3")
mycell = MyCellTableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: mycellid)
}
print("section3 config")
mycell?.title?.text = "\(city3[indexPath.row])"
mycell?.detailTitle?.text = "beautiful place"
mycell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
mycell?.imageView?.frame = CGRect(x: 0, y: 0, width: 50, height: 100)
mycell?.imageView?.image = UIImage(named:"test.png")
mycell?.selectionStyle = UITableViewCellSelectionStyle.Gray
return mycell!
}
}
//Sectionçš„å¤´éƒ¨æ ‡é¢˜
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "城市选择器"
}
//Sectionçš„å°¾éƒ¨æ ‡é¢˜
func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return "选择相应的城市"
}
//æœ‰å‡ ä¸ªéƒ¨åˆ†
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 3
}
//section尾部的高度
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 28
}
//section头部的高度
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 28
}
//section行的高度
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
if indexPath.section == 0
{
return 60
}
else if indexPath.section == 1
{
return 60
}
else
{
return 100
}
}
func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
class MyCellTableViewCell: UITableViewCell {
var title:UILabel?
var detailTitle:UILabel?
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
{
super.init(style: style, reuseIdentifier: reuseIdentifier)
title = UILabel(frame: CGRect(x: 100, y: 5, width: 50, height: 40))
detailTitle = UILabel(frame: CGRect(x: 100, y: 50, width: 50, height: 40))
self.addSubview(title!)
self.addSubview(detailTitle!)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Custom Cell, I want to let him in the third section shows, but when I pulled down the TableView, the third paragraph of section does not display the content. I don't know what's the problem.
enter image description hereenter image description here
I assume that there is something wrong the MyCellTableViewCell.
Maybe you can have a look at that or include it?
Are the print commands from part#3 printed in the console?
U need to dynamically change the height of the table using the following:
var noOfRows = city.count + city2.count + city3.count;
var currentHeight = self.tableView(tableView, heightForRowAtIndexPath: indexPath)
var finalHeight = noOfRows * Int(currentHeight);
You will need to place is the correct delegate function to make sure that when the table is rendered the height is changed.