Adjust SubView constraints on a UITableView Cell - ios

I have an UITableView with 2 section. The first section (VoucherCell) will be filled with data from a database. The second section (KodeVoucherCell) will be filled with data inputted by the user using a simple form. I create that simple form as a SubView (see picture below).
Then I set the second section to load the SubView using the code below :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell.init()
if(indexPath == NSIndexPath(forRow: 0, inSection: 1)) {
cell = tableView.dequeueReusableCellWithIdentifier("KodeVoucherCell")!
cell.addSubview(inputKodeVoucherSubView)
} else {
cell = tableView.dequeueReusableCellWithIdentifier("VoucherCell")!
cell.indentationLevel = indexPath.length - 1
cell.accessoryType = .DisclosureIndicator
cell.textLabel!.text = "Voucher A"
}
return cell
}
Now the problem is, although I have set the constraints of the SubView, while I run the app, it looks like this :
How to fix this? I tried to modify the constraint but still get the same look. Thanks.

You shouldn't be adding subviews directly to a UITableViewCell. Add them to the cell's contentView. Replace:
cell.addSubview(inputKodeVoucherSubView)
with:
cell.contentView.addSubview(inputKodeVoucherSubView)

Related

Some unwanted UIImageViews disappear while trying to set them as borders of UITableView

What I am trying to do is to replace borders(solid lines by default, of course) by small dots. I want the size of the dots to be 6 by 6.
Making borders invisible is a simple thing to do; I just set separators as 'None' in the attribute inspector.
But there was no field to set images or other objects as separators. To solve this problem, I splitted the dot into up and down pieces, assigned them in UIImageViews, and located the upper one on the bottom and the lower one on the top.
Then in the function tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath), I got the lower image in the first row and the upper image in the last row invisible.
What make the problem is that some unwanted dots disappear, while the dots I intended to change are properly gone away. Furthermore they come back or go away when the tableView is scrolled. The codes and the screenshot are below.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "reuseIdentifier"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MyListTableViewCell
//each element in datas[] has lowercase alphabets, a from q.
let array = datas[indexPath.row]
//data is a UIButton, which is the only component in each row besided those dots
cell.data.setTitle(array, forState: .Normal)
//this is where I typed to handle the unwanted dots on the very top and bottom
if indexPath.row == 0{
cell.lowerHalf.hidden = true
}
else if indexPath.row == datas.count - 1{
cell.upperHalf.hidden = true
}
///////////////////
return cell
}
When I scrolled tableView up and down side, it changed to this:
What makes the dots which shouldn't disappear go away? Or is their a better way to set images as borders?
+In the way iSashok suggested, things didn't change unfortunately. I applied this code right after the declaration; and then I moved to right before the return statement. Both did not work.
cell.clipsToBound = false
Your cell is getting reuse so you need to change your if condition of cellForRowAtIndexPath like this
if indexPath.row == 0 {
cell.lowerHalf.hidden = true
cell.upperHalf.hidden = false
}
else if indexPath.row == datas.count - 1{
cell.lowerHalf.hidden = false
cell.upperHalf.hidden = true
}
else {
cell.lowerHalf.hidden = false
cell.upperHalf.hidden = false
}
Try to modify for your cell clipsToBounds property in
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
like below
cell.clipsToBounds = false;
and for contentView the same
cell.contentView.clipsToBounds = false;
Why don't you use UITableViewHeaderFooterView? Simply create your view with that dot image in centre and return that view from viewForFooterInSection.

In Swift, I'd like the last 3 sections have only labels in their rows (and NOT text fields)

In my Swift project I have a table controller view with a table view inside. The table view is divided into 4 section and every section has 4 rows. Currently, each row is formed by a label beside a text field.
My purpose is that only rows in the first section has label beside text field. On the contrary, I want the last 3 sections have only labels in their rows (and NOT text fields).
Please, help me.
That's the code I wrote to manage with this problem but it's not working:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("index ", indexPath.section);
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath)
cell.textLabel?.text = self.items[indexPath.section][indexPath.row];
if(indexPath.section == 0){
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell") as! TextInputTableViewCell
cell.configure("", placeholder: "name")
}
return cell
}
It's not working because you are using the same cell for all the rows. You need to define two different rows. You can do this by setting prototype cells to more than one row (two in your case).
Each cell must have its own reuse identifier and it must be unique within that table view.
Then in your tableView(cellForRowAtIndexPath:) you can ask:
if indexPath.section == 0 {
cell = tableView.dequeueReusableCellWithIdentifier("firstSectionCell", forIndexPath: indexPath)
//
} else {
cell = tableView.dequeueReusableCellWithIdentifier("otherSectionCell", forIndexPath: indexPath)
//
}
Also note that in Swift you do not need to use parenthesis in if-statement (nor for, while, etc). So I suggest you remove them as they are pointless.
It looks like your cell in if(indexPath.section == 0) block doesn't actually have scope outside that block so any properties set there won't get returned there. If you just want to remove the textField, but keep the label, You can just set the textField.hidden = true. Here is how I would go about it.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("tableCell", forIndexPath: indexPath) as! TextInputTableViewCell
cell.textLabel?.text = self.items[indexPath.section][indexPath.row];
if(indexPath.section == 0){
cell.textField.hidden = false //Assumes TextInputTableViewCell's textField property is called "textField"
cell.configure("", placeholder: "name")
} else {
cell.textField.hidden = true //Not in first section we will hide textField
}
return cell
}
Doing it this way you can use the same cell class for every cell in your tableView, but just hide what you want based on its section.

How to Draw The View Controller with the Dyanamic Value

I have to make a view as image is below. I am confused and not able to darw Screen as Screen will have more Image on Bottom of Image as User will scroll the View and data on the Each time will come up Dynamically and Will on every time View Come up. Thanks any Help Appricated
after a long Research for this kind of view Finally i got a Solution Which is
take a Table View
take multiple Prototype Cell as much you Want
Set the Identifier Individually of each cell
create a Subcalss of UITableViewCell
Method like callForRowatindexPath you have to call like That with Diffrent Cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
var cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as? specificTopicTableViewCell`cell.textlabel.text = "Hello"
return cell!
}
else {
let cell2 = tableView.dequeueReusableCellWithIdentifier(kSecCellIdentifier) as? scondTopicTableViewCell
cell2.textlabel.text = "Hello"
return cell2!
}
}

Stop the reuse of custom cells Swift

I have an uitableview with a custom cell which gets data from the array.
Custom cell has an uilabel and an uibutton (which is not visible until the uilabel text or the array object which loads for the text - is nil).
On launch everything is fine. When i press the uibutton the array is being appended, the new cells are being inserted below the cell.
But when i scroll - all of a sudden the uibutton appears on other cells where this conditional uilabel text isEmpty is not implied.
Here is how the whole process looks like
Here is my code for cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:TblCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! TblCell
cell.lblCarName.text = someTagsArray[indexPath.row]
if let text = cell.lblCarName.text where text.isEmpty {
cell.act1.hidden = false
} else {
println("Failed")
}
cell.act1.setTitle(answersdict[answersdict.endIndex - 2], forState:UIControlState.Normal)
cell.act2.setTitle(answersdict.last, forState:UIControlState.Normal)
return cell
}
So my general question is how do i stop the reuse of those custom cells?
As far as i'm aware there is no direct way of doing this on reusablecellswithidentifier in swift, but maybe there are some workarounds on that issue?
When a cell is reused, it still has the old values from its previous use.
You have to prepare it for reuse by resetting that flag which showed your hidden control.
You can do this either in tableView:cellForRowAtIndexPath: or the cell's prepareForReuse method.
Update:
Here's an example you can add for TblCell:
override func prepareForReuse()
{
super.prepareForReuse()
// Reset the cell for new row's data
self.act1.hidden = true
}

How to hide content on specific cells only, despite using dequeueReusableCell?

I would like to hide some elements in a custom cell when we overpass a specific number of row. I added more row than the ones visible, because I needed to scroll until the last row without the bouncing effect. But now I have more cells, and I don't need the cells after row > 13.
I tried to setNeedsDisplay the cell with a if else, but the dequeue... method has a bad effect on the cells, when I scroll up, back to the previous cells, they don't have the texts anymore, like the row > 13. Is there a way to use the dequeue method, and let the content for the rows < 13, and remove the content for the rows > 13 ?
Here is some code :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var identifier = ""
if tableView == self.tableView{
identifier = "MyCell"
let cell = tableView.dequeueReusableCellWithIdentifier(identifier) as MyCell
if indexPath.row < 14 {
cell.showContent = true
cell.label.text = "test\(indexPath.row)"
}
else {
cell.showContent = false
cell.label.text = ""
cell.addItem.text = ""
}
cell.setNeedsDisplay()
return cell
}
//MyCell
override func drawRect(rect: CGRect) {
if !showContent {
label.text = ""
addItem.text = ""
}
else {
let path = UIBezierPath()//custom separator that should not be drawn for row > 13
Thanks
You shouldn't modify the text this way in drawRect. You already modified the labels in cellForRow. That's all you need.
That said, this isn't how I would do it. I'd probably create a different cell with its own identifier for empty cells. That way they can be really simple and you don't have to do things like cell.setNeedsDisplay() to get rid of the separator line. So in cellForRow, just return one kind of cell for data rows, and a different kind of cell for empty rows. There's no rule that says all the cells have to be the same class.

Resources