Im using NYXProgressiveImageView(https://github.com/Nyx0uf/NYXImagesKit) to load the image into cell progressively
When I’m scrolling getting duplicate images
How can i avoid this
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:#"Customcell"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
// Grab a pointer to the first object (presumably the custom cell, as that's all the XIB should contain).
cell = [topLevelObjects objectAtIndex:0];
}
[cell.Imageview1 loadImageAtURL:[NSURL URLWithString:MyURL]];//Here Imageview1 is NYXProgressiveImageView.
}
I think Its due to progressive download,I want to do similar to this http://nghiatran.me/advanced-issues-the-right-way-to-load-content-in-backgrounds-thread-with-tableview/
How to do this this with NYXProgressiveImageView class
Thank you..
You need to subclass UITableViewCell override prepareForReuse and set the imageView.image = nil. The cell's are reused in a table so unless you clean it out before it gets reused it will appear to "duplicate" your data.
You might give DFImageManager a try, it supports progressive image decoding and there are no known bugs. Check out demo project for an example on how to enable and use progressive decoding.
Related
This question is about rendering components of a user interface in Objective-C.
I am trying to get a green stripe to be displayed down the right hand side of a table cell whenever the data in it is considered valid.
In order to achieve this, I decided to create a UIView object, called validatedBar as a component of a custom UITableViewController object in the position and the shape of a thin green bar aligned along the right hand side of the table cell. When the table cell is being rendered to the display, I check to see whether the validatedBar needs to have its background colour set to green as opposed to the regular white. The following extract hopefully shows the relevant information:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *scheduleItem = #"ScheduleItemTableCell";
NSLog(#"cellForRowAtIndexPath");
ScheduleItemTableCell *cell = (ScheduleItemTableCell *)[tableView dequeueReusableCellWithIdentifier:scheduleItem];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ScheduleItemTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
ScheduleListItem *item = [self.scheduleItems objectAtIndex:indexPath.row];
// Other detail being loaded has been removed for brevity.
if(item.validated == YES){
NSLog(#"Should set the validated bar for list item number %ld",(long)indexPath.row);
cell.validatedBar.backgroundColor = [UIColor greenColor];
}
return cell;
}
When the cell is rendered, a green bar does not appear where I think it should even though I see the output displayed in the log.
What am I not doing? Is there anything not clear in this question that I should provide, or is there a pretty obvious solution?
I don't think this is correct...
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ScheduleItemTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
Without looking I don't think you can call LoadNibNamed at this point. It may work for you but it's definitely not by design and more by accident and thus, your view is not working properly and the background colour is not being changed as expected.
Try this approach...
NSString *CellIdentifier = #"ScheduleItemTableCell";
ScheduleItemTableCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ScheduleItemTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Can you see the difference in how the two code snippets?
Change this and the rest of your code should work. Let me know??
I have the feeling your layout might be wrong. To verify position the bar at the left of the cell (always visible). If that works, then fix your layout. Maybe you set the wrong constraint(s). And please also take the advice of #latenitecoder!
The reason you can't get it to change is because it has already been drawn during the drawRect stage of the view initialisation. That is why when you change orientation and it re-draws itself, you see your colour changed.
To make an immediate change, you will have to re-draw the UIView after setting the colour, as follows:
[cell.validatedBar setNeedsDisplay]
Note that this will not necessarily happen immediately after, but it notifies the view to re-draw as soon as possible. Apologies if the Obj-C code is wrong, I'm a Swiftie.
I'm finding that if you set a table view into editing mode, upon scrolling the table after deleting a row the cell edit control (the red minus sign on the left) is in a random state (turned vertical or horizontal) on the rest of the cells as you scroll the table. Presumably because I'm reusing cells like this:
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
How can I force the edit control to be in the correct state for each cell? It should always be in the default horizontal state unless I tap it to delete a cell.
EDIT: Here's the cell code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"WhateverIdentifier";
MyCell *cell = nil;
//This IF statement fixes the problem, but then I'm not reusing the cells
if (!tableView.isEditing) {
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
}
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:#"MyCell" owner:self options:nil] objectAtIndex:0];
}
//customize cell
return cell;
}
Are you calling [super prepareForReuse] in the method prepareForReuse of your custom cell?
That resolved my problem.
I just checked in a UITableView I had handy, and I don't see that problem. I'm using dequeueReusableCellWithIdentifier: as you are (without the if statement, of course). Are you doing something special with swiping, or deleting multiple rows or something?
(I'd make this a comment but can't yet. I'll delete it once you've resolved your problem.)
Is there an easy way of having a tableview cell like we see here with numbering like this and the border around. Is this created using different sections?
You need to create a custom UITableViewCell.
If you're using storyboards look here:
See this link http://mobile.tutsplus.com/tutorials/iphone/customizing-uitableview-cell/
If not here is a rundown:
Basically create a new class that inherits from UITableViewCell and a XIB. Drag a UITableViewCell to the XIB and set it to the class that you created previously.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CustomCellIdentifier = #"CustomCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell == nil) {
//*- Load your custom XIB. objectAtIndex:0 says load the first item in the XIB. Should be your UITableViewCell that you dragged onto your XIB in Interface Builder.
cell = [[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil] objectAtIndex:0];
}
//*- Customize the cell, i.e., cell.myLabel.text = #"Text";
return cell;
}
Using this technique you can layout your cell with three labels, one for the number and one for the name of the song and one for the song time. Add a background image view for the border and color.
A simple way to get the song number in the table is to use the indexpath.
cell.myLabel.text = [NSString stringWithFormat:#"%i", indexPath.row + 1];
I have a simple table with custom cells each containing a textfield. In cellForRowAtIndexPath: I create and initialize each cell depending on indexPath.row:
case 0:
{
CellIdentifier = #"TextEditCell";
TextEditCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
[cell configureCellWithText: [self.valueArray objectAtIndex:0]
placeholder: #"value no.0"]
[cell performAction: #selector(saveValue0:)
forControlEvent: UIControlEventEditingDidEnd
inTarget: self];
return cell;
}
configureCellWithText:placeholder: sets text and placeholder of cell's textField.
performAction:forControlEvent:inTarget refers directly to textField and saves the value of textField to local array to be accurate when used again.
Problem occurs, when I scroll the table fast. Values from different cells copy to another cells and modify local array. I can't find out why it happens. Anyone have any idea? I can provide more code if needed.
This is happening because you are reusing the cells and configureCellWithText is being run after the cell is reused. To solve this you could:
Don't reuse cells - But this would really hurt your performance.
If you are running on 6.0 you can use tableView:didEndDisplayingCell:forRowAtIndexPath: to cancel the text setting action when the cell scrolls off screen.
You can create a flag in your custom cell class that you set when you dequeue a cell.
Edit
Because I do not know how your cell works. It is hard for me to give you anything more then a sudo code concept.
Here is my sudo code:
Tableview Cell for row...
- dequeue cell
- [cell cancel_previous_action]
- set new actions.
I've done custom UITableViewCells before without issue.. but I can't figure out what is going on with my current project.
Here's what I've done...
Create CustomCell.h (subclassing UITableViewCell)
Create an empty XIB and drag in UITableViewCell. Set background to black.
Change class of UITableViewCell in Interface Builder to "CustomCell"
Import CustomCell.h in my DetailViewController
Modify tableView:cellForRowAtIndexPath:
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#"DO I GET HERE?");
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:nil options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
I would expect my tableview cells to show as black? But they are still showing as white... any ideas? Thanks!
Update: Ok, turns out, it is loading the custom cell... I added a UILabel with some white text. I couldn't see it, but when I highlighted the cell I could see the text was there. So now the question becomes, why is the cell ignoring the black background I have set for the cell?
EDIT: As for why it's not black - I expect there is something obscuring your black - the likeliest candidate for this is the label background being white and not clear.
As well as point 3.
The attributes inspector (the 4th tab) needs to have the reuse identifier set to the identifier you are going to reuse (you use #"cell" in your question). I would try and use something a bit more specific - after all in some apps you might have many types of custom cells.
I think you also need to cast the topLevelObjects to (CustomCell*) thus
if (cell == nil) {
NSLog(#"DO I GET HERE?");
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:nil options:nil];
cell = (CustomCell*)[topLevelObjects objectAtIndex:0];
}
Seems to ignore the background colour I've set, so I just add a UIView to it with a background colour and that seems to work..
You have to register your custom cell with the tableview
This needs to happen before that delegate is called:
[self.tableView registerClass: [CustomCell class] forCellReuseIdentifier:#"CellIdentifier"];