swift tableview separator line missing between first and second row - swift

I created a table and it seems the separator line between the first and second cell is missing and the rest are there. If I scroll to the top and back the line appears :
Below is the tableview rows functions. I read from a mysql database and display the rows.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return dbarray_id.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
//for(var i = 0; i < dbarray_id.count; i += 1)
//for i in 0..<dbarray_code.count
//{
// //newVars.put_timelog("cellForRowAtIndexPath_uiswitch :\(uiswitch_onoff[i]) \(uiswitch_enabled[i])")
//}
let cell = tableView.dequeueReusableCell(withIdentifier: "pushgroups_tvc") as! pushgroups_tvc
cell.backgroundColor = UIColor.clear
cell.txtsubject.text = dbarray_title[(indexPath as NSIndexPath).row]
cell.txtbody.text = dbarray_description[(indexPath as NSIndexPath).row]
cell.txtsubject.numberOfLines=0
cell.txtsubject.lineBreakMode = NSLineBreakMode.byWordWrapping
cell.txtbody.numberOfLines=0
cell.txtbody.lineBreakMode = NSLineBreakMode.byWordWrapping
cell.txtsubject.textColor = UIColor.blue
cell.txtsubject.font = newVars.font_subject
cell.txtbody.font = newVars.font_body
cell.addgroup.tag = (indexPath as NSIndexPath).row
//update switch to selected value
//cell.addgroup.on = false
cell.addgroup.isOn = uiswitch_onoff[(indexPath as NSIndexPath).row]
if uiswitch_enabled[(indexPath as NSIndexPath).row] == true
{
cell.addgroup.isEnabled = true
cell.addgroup.backgroundColor = UIColor.clear
}
else
{
cell.addgroup.isEnabled = false
cell.addgroup.backgroundColor = UIColor.clear
}
cell.txtaccesscode.text = ""
cell.txtaccesscode.isEnabled = true
cell.txtaccesscode.tag = (indexPath as NSIndexPath).row
cell.txtaccesscode.tintColor = UIColor.blue
cell.txtaccesscode.autocapitalizationType = .allCharacters
//GGGGGG
cell.txtaccesscode.addTarget(self, action: #selector(textFieldTyping_access), for: .editingChanged)
if dbarray_public[(indexPath as NSIndexPath).row] == "Y"
{
//cell.backgroundColor = UIColor.blueColor().colorWithAlphaComponent(0.2)
cell.txtaccesscode.text = ""
cell.txtaccesscode.isEnabled = false
cell.addgroup.isEnabled = true
cell.txtaccesscode.isHidden = true
}
if dbarray_public[(indexPath as NSIndexPath).row] == "R"
{
cell.txtaccesscode.isHidden = false
//cell.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.2)
}
if dbarray_public[(indexPath as NSIndexPath).row] == "H"
{
//cell.backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.2)
}
cell.selectionStyle = .none
cell.layoutMargins = UIEdgeInsets.zero
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero
cell.backgroundColor = newVars.hexStringToUIColor(hex: newVars.tableview1_background_color).withAlphaComponent(CGFloat(newVars.tableview1_background_color_alpha))
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
newVars.put_timelog(timedata: "GORDON pushgroups_vc_textFieldDidBeginEditing(textField ")
//tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLineEtched
tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine
tableView.separatorColor = UIColor.black
//tableView.backgroundColor = UIColor.red //overrides cell color
tableView.showsHorizontalScrollIndicator = false
tableView.showsVerticalScrollIndicator = false
}

I believe that setting:
cell.selectionStyle = .none
And then programmatically selecting a cell, like in the viewDidLoad method will cause this bug.
I had the same problem and solved it using accessory checkmark and disabling selection. After I removed the code that selected the first cell by default, the bug disappeared.

Related

Checkbox not working separately in swift. How can I make it separate?

I have problem about checkbox in swift. I use M13Checkbox, found in github. In my app when I click at index 0 cell's checkbox, all even numbers(index) cells checkboxs checked. And also when I click at index 1 cell's checkbox all odd numbers(index) cell's checkboxs get checked. I can't find any reason for that Can anybody help me?
Here my code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: sipCellId, for: indexPath) as! sipCell
var searched: String?
if isSearching {
searched = filteredArray[indexPath.row]
}else{
searched = self.orderId[indexPath.row]
}
cell.orderIdLabel.text = searched
//cell.orderIdLabel.text = self.orderId[indexPath.row]
cell.detailLabel.text = self.newDatas[indexPath.row]
cell.alindiLabel.text = "Alındı: "
cell.temizlemedeLabel.text = "Temizlemede: "
cell.teslimEdildiLabel.text = "Teslim edildi: "
cell.kapidaOdemeLabel.text = "Kapıdan alınacak tutar: \(self.ucret[indexPath.row])"
cell.deleteButton.tag = indexPath.row
cell.urunEklemeButton.tag = indexPath.row
cell.uncheckedButtonAlindi.tag = indexPath.row
cell.uncheckedButtonTemizleme.tag = indexPath.row
cell.uncheckedButtonTeslim.tag = indexPath.row
return cell
}
Here my checkbox function:
#objc func checkControlAlindi(sender : M13Checkbox?) {
switch sender!.checkState {
case .checked:
let indexPath = IndexPath(row: (sender!.tag), section: 0)
let cell = tableView.cellForRow(at: indexPath) as! sipCell
print(cell.orderIdLabel.text!)
print("alındı kısmına bastınız... ", (sender!.tag))
break
case .unchecked:
print("unchecked")
break
case .mixed:
//empty...
break
}
}
And here my checkbox:
let uncheckedButtonAlindi: M13Checkbox = {
let button = M13Checkbox()
button.tintColor = .orange
button.boxType = .circle
button.secondaryTintColor = .lightGray
button.boxLineWidth = 4
button.checkmarkLineWidth = 3
button.addTarget(self, action: #selector(ViewController.checkControlAlindi(sender:)), for: UIControl.Event.valueChanged)
return button
}()

UITableViewCell Selected Background Color on DidSelectRow

I want to change the background when I select the table. Right now, when I select two tables, the background changes to 2. I just want to change the background of the last table I chose. So just change the background of one table, not two. Change the background of the last painting I chose.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableView1 {
let cell:DeviceTableViewCell2 = tableView1.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
cell.selectionStyle = .none
cell.backgroundColor = GradientColor(UIGradientStyle.diagonal, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
}
if tableView == self.tableView2 {
let cell:DeviceTableViewCell2 = tableView2.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
cell.selectionStyle = .none
cell.backgroundColor = GradientColor(UIGradientStyle.diagonal, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
}
if tableView == self.tableView3 {
let cell:DeviceTableViewCell2 = tableView3.dequeueReusableCell(withIdentifier: cellIdNew2, for: indexPath) as! DeviceTableViewCell2
cell.selectionStyle = .none
cell.backgroundColor = GradientColor(UIGradientStyle.diagonal, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView == self.tableView1 {
let selectedCell:UITableViewCell = tableView1.cellForRow(at: indexPath)!
selectedCell.contentView.backgroundColor = UIColor.flatGray
}
if tableView == self.tableView2 {
let selectedCell2:UITableViewCell = tableView2.cellForRow(at: indexPath)!
selectedCell2.contentView.backgroundColor = UIColor.flatGray
}
if tableView == self.tableView3 {
let selectedCell3:UITableViewCell = tableView3.cellForRow(at: indexPath)!
selectedCell3.contentView.backgroundColor = UIColor.flatGray
}
Do not change the backgroundColor of the contentView or of the cell itself, use the selectedBackgroundView instead:
cell.backgroundView = UIView()
cell.backgroundView?.backgroundColor = // your color when not selected
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView?.backgroundColor = // your color when selected
After this initial setup, there is no need to change anything. Everything will work automatically.
Do not set cell.selectionStyle = .none because that will disable selection completely.

“Thread 1: Fatal error: Index out of range in Swift” from TableView

I want to pull the data from chipnumber2 and chipnumber. I want to collect the two in a table, but there's a problem. How do I draw data from two text tables? "let deviceItem: Device3New = itemsNew[indexPath]".I'm getting this problem on the row. In short, I want to draw the data in Device3New and device3 to the same table. How can I do that?
class NewMainTableViewController: UITableViewController {
var items: [Device3] = []
var itemsNew: [Device3New] = []
let cellId: String = "cellId"
let cellIdNew: String = "cellIdNew"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(DeviceTableViewCell2.self, forCellReuseIdentifier: cellId)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if !chipnumber2.text!.isEmpty {
let cellNew = tableView.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3New = itemsNew[indexPath.row]
cellNew.badgeColor = UIColor.flatLime
cellNew.badgeTextColor = .white;
cellNew.badgeFontSize = 13;
cellNew.badgeString = deviceItem.time
cellNew.badgeOffset = CGPoint(x:30.0, y:63)
cellNew.textLabel?.text = deviceItem.title
cellNew.deviceItem3New = deviceItem
cellNew.titleNew.text = deviceItem.title
cellNew.title1New.text = deviceItem.places
cellNew.titlesaatNew.text = deviceItem.time
cellNew.buttonNew.isOn = deviceItem.state
cellNew.tablerow = String (indexPath.row)
cellNew.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cellNew
}
if !chipnumber.text!.isEmpty {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3 = items[indexPath.row]
cell.badgeColor = UIColor.flatLime
cell.badgeTextColor = .white;
cell.badgeFontSize = 13;
cell.badgeString = deviceItem.time
cell.badgeOffset = CGPoint(x:30.0, y:63)
cell.textLabel?.text = deviceItem.title
cell.deviceItem3 = deviceItem
cell.title.text = deviceItem.title
cell.title1.text = deviceItem.places
cell.titlesaat.text = deviceItem.time
cell.button.isOn = deviceItem.state
cell.tablerow = String (indexPath.row)
cell.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cell
}
return UITableViewCell()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !chipnumber2.text!.isEmpty {
return itemsNew.count + items.count
} else if !chipnumber.text!.isEmpty {
return items.count
}
return 0
}
The problem is that cellForRowAt it trying to handle a scenario where there are two arrays, but both deviceItem assignments are using the same indexPath.row as an index within the respective array. But if items has two items and newItems has three, the cellForRowAt will called five times, with indexPath.row values ranging between 0 through 4. But you’re using indexPath.row in both arrays, and so you’re going to go beyond the bounds of the array for one or both of items and newItems.
The easiest solution is to have two sections, one for items and another for newItems. That gets you out of the business of having to figure out which indexPath belongs to which array:
override func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return itemsNew.count
} else {
return items.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cellNew = tableView.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem = itemsNew[indexPath.row]
...
return cellNew
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem = items[indexPath.row]
...
return cell
}
}
Note, I’m not looking at the text fields. The above assumes that you’ll just populate both arrays (and call tableView.reloadData()).
it because you add items and ItemsNew for define the tableViewCell, you should use just one of them or use a protocol for sync them as well.
so here is the correct code
class NewMainTableViewController: UITableViewController {
var items: [Device3] = []
var itemsNew: [Device3New] = []
var sumItems: []
let cellId: String = "cellId"
let cellIdNew: String = "cellIdNew"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(DeviceTableViewCell2.self, forCellReuseIdentifier: cellId)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if !chipnumber2.text!.isEmpty {
let cellNew = tableView.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3New = itemsNew[indexPath.row]
cellNew.badgeColor = UIColor.flatLime
cellNew.badgeTextColor = .white;
cellNew.badgeFontSize = 13;
cellNew.badgeString = deviceItem.time
cellNew.badgeOffset = CGPoint(x:30.0, y:63)
cellNew.textLabel?.text = deviceItem.title
cellNew.deviceItem3New = deviceItem
cellNew.titleNew.text = deviceItem.title
cellNew.title1New.text = deviceItem.places
cellNew.titlesaatNew.text = deviceItem.time
cellNew.buttonNew.isOn = deviceItem.state
cellNew.tablerow = String (indexPath.row)
cellNew.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cellNew
}
if !chipnumber.text!.isEmpty {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3 = items[indexPath.row]
cell.badgeColor = UIColor.flatLime
cell.badgeTextColor = .white;
cell.badgeFontSize = 13;
cell.badgeString = deviceItem.time
cell.badgeOffset = CGPoint(x:30.0, y:63)
cell.textLabel?.text = deviceItem.title
cell.deviceItem3 = deviceItem
cell.title.text = deviceItem.title
cell.title1.text = deviceItem.places
cell.titlesaat.text = deviceItem.time
cell.button.isOn = deviceItem.state
cell.tablerow = String (indexPath.row)
cell.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cell
}
return UITableViewCell()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !chipnumber2.text!.isEmpty {
return itemsNew.count //+ items.count
} else if !chipnumber.text!.isEmpty {
return items.count
}
return 0
}

TableView with multiple cell

I'm calling in two separate data in my table. I can change the first call to the data, for example, I can use the switch button. But I can't use the switch button of the data I added in the second, so I can't use the didSelectRowAt property of the data. I can't use the switch button of deviceitemnew, but I can't use didSelectRowAt. So the cell in the code.buttonNew. I can't use the addTarget feature. Probably " return items."count " is a matter of concern.
Click on the button above the photo, click on the button below.
var items: [Device] = []
var itemsnew: [NewDevice] = []
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: cellId, for: indexPath) as! DeviceTableViewCell
if newdevicechipnumber.isHidden == false {
let deviceItemNew: NewDevice = itemsnew[indexPath.row]
cell.new = deviceItemNew
cell.titleNew.text = deviceItemNew.titleNew
cell.title1New.text = deviceItemNew.placesNew
cell.titlesaatNew.text = deviceItemNew.timeNew
cell.buttonNew.isOn = deviceItemNew.stateNew
cell.buttonNew.addTarget(self, action: #selector(refreshDataNew), for: .touchUpInside)
return cell
}
let deviceItem: Device = items[indexPath.row]
cell.badgeColor = UIColor.flatLime
cell.badgeTextColor = .white;
cell.badgeFontSize = 13;
cell.badgeString = deviceItem.time
cell.badgeOffset = CGPoint(x:70.0, y:50.0)
cell.deviceItem = deviceItem
cell.title.text = deviceItem.title
cell.title1.text = deviceItem.places
cell.titlesaat.text = deviceItem.time
cell.button.isOn = deviceItem.state
cell.button.addTarget(self, action: #selector(refreshData), for: .touchUpInside)
tablerow = String (indexPath.row)
cell.tablerow1 = tablerow
cell.backgroundColor = UIColor(white: 1, alpha: 0.09)
return cell
}

Shadow on a UITableViewCell disappears when scrolling

I have a UITableView that has one cell with a shadow. When I do scrolling up and down, the shadow of the cell disappears. As I thought this was a reuse-issue I already only ever use this one cell with a shadow.What may be the problem here ?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
switch indexPath.row {
case 3: cell = shadowBasicCellAtIndexPath(indexPath)
case 4: cell = contentCellAtIndexPath(indexPath)
case 5: cell = contentCellAtIndexPath(indexPath)
case 6: cell = contentCellAtIndexPath(indexPath)
case 11: cell = contentCellAtIndexPath(indexPath)
default: cell = basicCellAtIndexPath(indexPath)
}
return cell
}
func contentCellAtIndexPath(indexPath: NSIndexPath) -> ContentCell {
let cell = tableView.dequeueReusableCellWithIdentifier(contentCellIdentifier) as! ContentCell
setTitleForCell(cell, indexPath: indexPath)
setContentForCell(cell, indexPath: indexPath)
return cell
}
func shadowBasicCellAtIndexPath(indexPath: NSIndexPath) -> ShadowBasicCell {
// let cell = tableView.dequeueReusableCellWithIdentifier(shadowBasicCellIdentifier) as! ShadowBasicCell
let cell = tableView.dequeueReusableCellWithIdentifier(shadowBasicCellIdentifier, forIndexPath: indexPath) as! ShadowBasicCell
// let cell = ShadowBasicCell(style: <#T##UITableViewCellStyle#>, reuseIdentifier: <#T##String?#>)
cell.icon.image = upperTableIcons[indexPath.row]
cell.textlabel.text = upperTableLabels[indexPath.row]
cell.textlabel.textColor = UIColor.dmvBody1()
cell.textlabel.font = UIFont.dmvBody1()
cell.valueLabel.font = UIFont.dmvBody1()
cell.selectionStyle = UITableViewCellSelectionStyle.None
cell.layer.shadowColor = UIColor.blackColor().CGColor
cell.layer.shadowOffset = CGSizeMake(5, 5);
cell.layer.shadowOpacity = 0.2;
cell.layer.shadowRadius = 3.0;
cell.clipsToBounds = false
let shadowFrame: CGRect = (cell.layer.bounds)
let shadowPath: CGPathRef = UIBezierPath(rect: shadowFrame).CGPath
cell.layer.shadowPath = shadowPath
cell.separatorInset = UIEdgeInsets.init(top: 0, left: cell.frame.width, bottom: 0, right: 0)
return cell
}
func basicCellAtIndexPath(indexPath: NSIndexPath) -> BasicCell {
let cell = tableView.dequeueReusableCellWithIdentifier(basicCellIdentifier) as! BasicCell
cell.icon.image = upperTableIcons[indexPath.row]
cell.textlabel.text = upperTableLabels[indexPath.row]
cell.textlabel.textColor = UIColor.dmvBody1()
cell.valueLabel.text = upperTableValues[indexPath.row]
cell.valueLabel.textColor = UIColor.dmvBody1()
cell.textlabel.font = UIFont.dmvBody1()
cell.valueLabel.font = UIFont.dmvBody1()
cell.selectionStyle = UITableViewCellSelectionStyle.None
if indexPath.row > 6 {cell.backgroundColor = UIColor.dmvBeige30()} else {
cell.backgroundColor = UIColor.whiteColor()
}
return cell
}
I solved the problem myself: The reason the shadow wasn't seen, was because it was covered by the cell beneath that got redrawn. I set the background color of the following cell to clearColor() and everything is fine now.