Edit only the first cell in a UITableView - ios

I am trying to add a gradient to the first cell in my UITableView.
Here is the if statement I use to determine if the cell is the first in the table.
if (indexPath.row == 0 && indexPath.section == 0) {
This code does not seem to be working as there are a few cells with the gradient, notably the first and last cell along with sometimes the second cell. This is rather odd as the information I am grabbing in the array using indexPath.row is getting the information from the correct position.
Why is my if statement not working? Even though I am grabbing information from the correct location in the array.

You are probably not implementing prepareForReuse in your custom UITableViewCell subclass. It looks like you are correctly targeting the first cell, so perhaps when that cell is later reused for other index paths you aren't clearing the gradient you added earlier.

Make sure you have an else condition to go along with your if. Because table view cells are reused, you need to make sure to remove the gradient if it is in a cell other than the first one.
if(first cell)
add gradient
else
remove gradient if it exists

If you're using custom cells, set the custom cell gradient variable to clear colour on all but the first cell.
If you're using standard uitableview cells, add the gradient to every cell as default and then if it's your first cell change the gradient colours to whatever you need it to be, and clear colour as default.
Alternatively clean all subviews from the cell after allocating it like this:
for (UIView * sub in cell.subviews){
[sub removeFromSuperview];
}
Then add your gradient for the first cell.
Option 1 is the cleanest.

Related

UITableViewCell repeating with scrollview - What workarounds are there?

So, my problem is pretty simple. I have a UITableView in a UIViewController. The tableview has dynamic cells (custom cells with images , text, etc.. from a subclass I created) and these cells belong to a subclass I created. Everything is going fine since the content is different on each cell. The problem is that when I scroll the scrollview of the cell which is horizontal ( I have a UIScrollView in the subview of the cell. I created this scrollview on the cell subclass), on let's say, indexPath.row == 0, and scroll the tableview vertically, after about 8 cells, the ninth cell has the scrollview scrolled as well. This is because of dequeuereusablecells, so the ninth cell is actually the first one, only displaying different content but since it is the first cell, it has the same background operation (the scrollview scrolled).
I tried to unscroll in the cellForRowAtIndexPath: but although this solves the problem it creates another : The first cell that was scrolled is not anymore. So, to solve this new problem I am planning on adding a workaround here that is a dictionary of [Int:Bool], that is, the indexPath corresponding to a Boolean value. If I scrolled the first cell, then 0:true. If I reach the ninth cell (which is equal to the first cell, but with IndexPath = 8 ), I unscroll the cell's horizontal scrollview. If I come back to the beginning of the tableview and reach the first cell, I scroll the cell's horizontal scrollview back. What do you guys think?
The other workaround I can think of is just not use dequeue reusable cells since I don't think I will have more than 30-50 rows on my tableview.
In terms of performance, which operation is better?
Firstly, I would suggest you to carefully analyse whether removing scrolling offset from the first cell is such a bad idea. If I am a user and I scroll down to the very bottom, making the first cell invisible, are you sure that I want it to return to the scrolled position after I scroll back to top? The answer might be Yes, but you should think about this carefully because it might lead you to the simplest solution.
However, in case you really need to do it, I would have a variable which stores the state of the scrolling for each row. If you have an array of objects from which you pull necessary properties (title, image etc) you can add this as an extra property to these objects. Otherwise, you can create an array which will be storing this info (I would prefer an array over dictionary for this task).
Fundamentally it's an issue caused by table view cell reusability. You can have workarounds, but I'd say that, things that aren't supposed to be reused should not be reused.
If your cells are all similar (with minor differences), you could use just one cell identifier; If you have very different types of cells, say, one type has a horizontal scroll view inside, one type just has some labels and images, you might want to consider to have two identifiers, so cells that have UIScrollView won't be reused for normal cells.
And at the same time, you can still do necessary cleanup works in prepareForReuse: to make sure cells that just get dequeued have a fresh start.

TableViewCell with SegmentControl

I have tableview in which a particular cell has the UISegmentedControl in it.
My doubt is when a particular segment is selected I need to expand the cell and show the information below and need to hide it when the other segment is selected.
For Ex:
I have three segment A, B and C. When selecting the segment B, I need to show switch below the segment and when the other two segments are selected nothing must be displayed below the segment.
Your dataSource's objects should have an "extended" property.
Each time a segmentedControl is changed, update your dataSource accordingly and reload your cell.
When you configure your cell, change its size depending on the "extended" property of the object.
Theres a few things to do here. You need to make sure your tableview is using automatic dimension for its cell height. Dont use the -heightForRowAtIndexPath method (remove it). Instead set two properties on the tableview :
[self.tableview setEstimatedRowHeight:110];
[self.tableview setRowHeight:UITableViewAutomaticDimension];
This enables proper autolayout (in case you havent already) for each cell.
You will need to have a subclass of UITableViewCell in code, if you havent already (sorry for skipping over some quite big things!). Add the information label to your cell in Interface Builder. Give it a height constraint, and then drag this height constraint into your cell subclass so you can change it.
Now put your code for handling the segmented control in the subclass. When you detect that the central segment has been selected, then affect the height constraint of your information label, like this :
self.labelHeightConstraint.constant = 40;
You may also need a call to setNeedsLayout :
[self setNeedsLayout];
Apologies for the brevity - hopefully this will point you in the right direction. There are some other details - for eg on -prepareForReuse method (on the cell) you can set the height of the info label to 0 (and call setNeedsLayout again).

UITableViewCell highlight only part of the cell?

I have a standard UITableViewCell on which I add a few extra views to in order to create a custom look. One of these such views is a UILabel that I've put a border and background color on, in order for it to look sort of like a separate bubble. When a user taps on the cell, I want it to still highlight, but only on where this UILabel is, not the entire cell (it looks ugly when it highlights the whole cell). How can I do this?
Anything with the selection style of the cell seems to only change the color or style, but I want to change the area of the cell that is highlighted.
Thanks in advance.
Another way to achieve it is,
In CellForRowAtIndexPath, check whether the index path of the cell you are rendering is same as tableview.indexPathForSelectedRow. If same, give a highlighted look which you want.
In didSelectRowAtIndexPath reload the previously selected cell and currently selected cell.
[You have to cache the previous selected index to reset the highlighted look.]

position custom cell in a tableview not fully showing a cell

Okay What i want to do is position a custom cell so that the cell looks like only a portion of it is shown in the UITableView. When you swipe it to the left it goes to a new viewcontroller that allows the user to add details for a new cell. My question is how do we position the UITableViewCell to show only a portion of it in the tableView?
What i want to do is position a custom cell so that the row is not shown fully like about 1/4th or 1/2 its actual length only in the table view
here is an app with the functionality i'm trying to implement this is the image url as i can't post images yet
http://a3.mzstatic.com/us/r30/Purple6/v4/01/16/ec/0116ec99-0206-d125-7d27-d5956b918635/screen568x568.jpeg
I want to implement my cells just like how they implemented their expenses in cells, the cell is positioned according to the amount in it ,if the amount is high the cell is placed further to the left else only 1/4th of the cell is shown(empty cell no expense )
Can we achieve this by making an imageview in a customcell and then changing the x-axis of the image view according to the amount entered in the cell? Thanks in advance
For this, I would do it this way :
For each of my model cell I add a state, in the delegate of UItableView i use heightForRowAtIndex to set the size depends of the cell's state.
To not show extra view (when the cell is cliped) use :
[myCellview setClipToBounds:YES];
I think it should do the tricks. Even if it's not the best way to do it!
Solved it i Just had to add a scroll view to the cell's content view and then add a view containing the color to the scroll view. So its coding is similar to the swipe deletion in 'UITablView'
https://github.com/TeehanLax/UITableViewCell-Swipe-for-Options
this repository helped me out, i only had to make a few changes otherwise that was it thanks for all your suggestions :)

Check if image is empty for reused cells

Each cell has an image.
I want to be able to check if the image is empty.
I am using tableView's reuseIdentifier.
I have tried to do the following
if (!cell.imageView.image) {
}
and
if (CGSizeEqualToSize(cell.imageView.image.size, CGSizeZero)) {
}
But none of these approaches work, as the cell thinks the image exists, because previous cell's images exist (due to reused cells)
How do I get around this problem? How do I check if a cell's image is empty or not in a reused cell?
Technically if the cell is reused, the image won't be nil (unless you didn't set it). So if you want to not reuse the images from your cells you can use -prepareForReuse method from UITableViewCell, this method is called right before the cell is reused, so in this method you can make the image nil.

Resources