I tried to load dynamic images in imageview and text in label ,its working fine in both simulator and ios device. (see below code)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ImageCell *cell = (ImageCell *)[self.TestTable dequeueReusableCellWithIdentifier:#"ImageCell"];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ImageCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
}
else
{
if (cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ImageCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
}
cell.textlabels.text=#"Cable and Hose Carriers";
cell.ProductsImages.image = [UIImage imageNamed:#"cool.jpg"];
return cell;
}
But if i tried to load a data in uitextview in the custom tableview cells ,tableview is not scroll smoothly (stutter) in ios device but works fine in simulator.Please advise me to do it better.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ImageCell *cell = (ImageCell *)[self.TestTable dequeueReusableCellWithIdentifier:#"ImageCell"];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ImageCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
}
else
{
if (cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ImageCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
}
cell.ProductsDetailsTextView.delegate = self;
cell.ProductsDetailsTextView.text=[Descriptions objectAtIndex:indexpath.row];
return cell;
}
You are trying to do all things ON main thread. Your main thread starts blocking due to dynamic loading of data thats why tableview is not scrolling smoothly. Try to write code in different queue
// call background queue for dynamic loading of data
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// load your dynamic data here
// call main queue here
dispatch_async(dispatch_get_main_queue(), ^{
// after loading data in background. use your downloaded data here.
});
});
Thats It.
Related
Hi friends it is a Strange Issue I'm facing, I am using Multiple UItableCustomCells in one Grouped TableView with Section's.
I am able to Select first Section's rows only, then when I click on another Section's row it's selection method is not working, I can not understand where is mistake, my cellForRowAtIndexPath code is Below:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier =[NSString stringWithFormat:#"%d",indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//if (cell == nil) {
if(indexPath.section==0)
{
if(indexPath.row==0)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell1" owner:self options:nil];
cell = self.Cell1;
self.Cell1 = nil;
txtincidentName = (UITextField*)[cell.contentView viewWithTag:1];
}
else if(indexPath.row==1)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell2" owner:self options:nil];
cell = self.Cell2;
self.Cell2 = nil;
lblDatefirst = (UILabel*)[cell.contentView viewWithTag:2];
btnCalfirst = (UIButton*)[cell.contentView viewWithTag:3];
lblTimeFirst = (UILabel*)[cell.contentView viewWithTag:4];
}
else if(indexPath.row==2)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell2" owner:self options:nil];
cell = self.Cell2;
self.Cell2 = nil;
lblDatefirst = (UILabel*)[cell.contentView viewWithTag:2];
btnCalfirst = (UIButton*)[cell.contentView viewWithTag:3];
lblTimeFirst = (UILabel*)[cell.contentView viewWithTag:4];
lblInciTime =(UILabel*)[cell.contentView viewWithTag:9];
lblInciTime.text=#"Date/Time";
}
}
else if(indexPath.section==1)
{
if(indexPath.row==0)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell3" owner:self options:nil];
cell = self.Cell3;
self.Cell3 = nil;
btndropDown1 = (UIButton*)[cell.contentView viewWithTag:5];
btndropDown2 = (UIButton*)[cell.contentView viewWithTag:6];
btndropDown3 = (UIButton*)[cell.contentView viewWithTag:7];
}
else if(indexPath.row==1)
{
[[NSBundle mainBundle]loadNibNamed:#"CustomCell4" owner:self options:nil];
cell = self.Cell4;
self.Cell4 = nil;
txtViewofdetails = (UITextView*)[cell.contentView viewWithTag:7];
}
}
return cell;
}
simulator image
Please Help and guide Thank you..
Don't load the cells from nibs like this. Instead register the cells with a reuse identifier in the NIB. This will cause the dequeueing pick the correct cell protoype based on the identifier.
Most likely your current approach messes up the touch handling of the table view.
hey try this type of concept and flow of the code
NSString *CellIdentifier =[NSString stringWithFormat:#"%d%d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell1" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell1 *) currentObject;
break;
}
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you load custom UITableViewCells from Xib files?
Here is my code ..
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LibraryListingCell";
DVDListingViewCell *cell = (DVDListingViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"DVDListingView" owner:self options:nil];
cell = [_cell autorelease];
_cell = nil;
}
cell.titleLabel.text = [[dao libraryItemAtIndex:indexPath.row] valueForKey:#"title"];
cell.featureLengthLabel.text = [NSString stringWithFormat:#"%# minutes",
[[dao libraryItemAtIndex:indexPath.row] valueForKey:#"featureLength"]];
cell.coverImageView.image = [UIImage
imageNamed:[[dao libraryItemAtIndex:indexPath.row] valueForKey:#"coverImage"]];
return cell;
}
How to solve Thread1 : Signal SIGABRT problem with this line [[NSBundle mainBundle] loadNibNamed:#"DVDListingView" owner:self options:nil];
I would advise to try this, while making sure that you "DVDListingView.xib" is the NIB for the custom cell ONLY
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LibraryListingCell";
DVDListingViewCell *cell = (DVDListingViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"DVDListingView" owner:self options:nil];
for(id currentObject in topLevelObjects){
if([currentObject isKindOfClass:[DVDListingViewCell class]]){
cell = (DVDListingViewCell *)currentObject;
break;
}
}
}
cell.titleLabel.text = [[dao libraryItemAtIndex:indexPath.row] valueForKey:#"title"];
cell.featureLengthLabel.text = [NSString stringWithFormat:#"%# minutes",
[[dao libraryItemAtIndex:indexPath.row] valueForKey:#"featureLength"]];
cell.coverImageView.image = [UIImage
imageNamed:[[dao libraryItemAtIndex:indexPath.row] valueForKey:#"coverImage"]];
return cell;
}
The line
[[NSBundle mainBundle] loadNibNamed:#"DVDListingView" owner:self options:nil];
returns an NSArray. It needs to be like this:
NSArray *xibObjectArray = [[NSBundle mainBundle] loadNibNamed:#"DVDListingView" owner:self options:nil];
//retrieve items from the array
if (xibObjectArray.count == 1) {
cell = [xibObjectArray objectAtIndex:0];
} else {
for (UIView *randomView in xibObjectArray) {
if ([randomView isKindOfClass:[DVDListingViewCell class]]) {
cell = (DVDListingViewCell *)randomView;
}
}
}
In CustomCell.m I define init method where I want to load cell from the IB:
- (id)init {
self = [super init];
if (self) {
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
self = [nib objectAtIndex:0];
}
return self;
}
In the MyTableViewController.m in the method cellForRowAtIndexPath I initialize my custom cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cell=[[CustomCell alloc]init];
return cell;
}
Everything works as I expected but when I did Product -> Analyse I get
Returning 'self' while it is not set to the result of '[(super or self) init...]'
What am I doing wrong?
You are overwriting self (returned from super init) with the object returned from your array. If you want to load a custom cell from a nib, do it in your cellForRowAtIndexPath method, or create a convenience class method on your custom cell that loads from the nib:
In your cellForRowAtIndexPath:
cell = [CustomCell cell];
In your cell's implementation:
+(CustomCell*)cell
{
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
return [nib objectAtIndex:0];
}
EDIT - changed method name since new* indicates that a retained object will be returned.
Keep your init method as below, and do the linking in the Interface Builder
- (id)init {
self = [super init];
if (self) {
}
return self;
}
And
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell *) currentObject;
break;
}
}
}
}
What I am doing is
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// Initialization code.
//
UITableViewCell *view = [[[NSBundle mainBundle] loadNibNamed:#"SmallCellView" owner:self options:nil] lastObject];
self.backgroundView = view;
}
return self;
}
then in the main class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
SmallCellView *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[SmallCellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
For me this is working fine and in Product -> Analyse is not giving any warning or error
I met the same problem, I have fixed it by removing the code that like
NSArray *nib =[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
return [nib objectAtIndex:0];
from the CustomView's definition init Method.
Put these code the at the place where you create the Custom.
I'm looking for solution...
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"ItemCardapio";
NSString *nibName = #"ItemCardapioCell";
ItemCardapioCell *cell = (ItemCardapioCell *) [self.restaurantsList dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];
cell = (ItemCardapioCell *)[nib objectAtIndex:0];
[cell initCellWithRestaurant:#"" tipoRestaurante:#""];
}
return cell;
}
I find that with problems with cell repeating, the problem tends to occur when you put stuff you shouldn't in the if (cell == nil) bit.
The reason being is that the table view will end up using an incorrect re-used cell if you don't update certain aspects of your cell appropriately.
Try taking anything which directly changes your cell out of that if (cell == nil) bit, and it should stop problems with repeating cells.
Heres what I use for Custom cells:
static NSString *cellIdentifier = #"ItemCardapioCell";
ItemCardapioCell *cell = (ItemCardapioCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
NSLog(#"Creating Cell");
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ItemCardapioCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[ItemCardapioCell class]])
{
cell = (ItemCardapioCell *)currentObject;
break;
}
}
};
Is there a way to use multiple uitableviewcell classes with nib files in the tableViewController?
There's this great tutorial video for how to create custom cell classes to be used in a tableViewController at the cellForRowAtIndexPath function that I'm pasting here in case anyone wants to see.
In this example though, they are only using one type of reusable cell class. This is from my own project but it's essentially what the tutorial presents. "videoCellEntry" is a custom cell that I have created with nib file videoEntryCell.xib, "videoEntry" is the class for each cell that I am configuring, and "videos" is an array of videoEntry.
I'm assuming to use multiple nib files, I can put some conditions to choose which nib file I want and then call a different loadNibNamed: portion like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"videoCellId";
videoEntryCell *cell =
(videoEntryCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if(<condition 1>) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"videoEntryCell" owner:self options:nil];
}
if(<condition 2>) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"videoEntryCell2" owner:self options:nil];
}
cell = (videoEntryCell *)[nib objectAtIndex:0];
}
// Configure the cell.
videoEntry *vid = [videos objectAtIndex:indexPath.row];
[cell configureForVideoEntry:vid];
return cell;
}
But can the tableViewController handle multiple cell nib files? Or is there a better way? And wouldn't each cell require a different CellIdentifier depending on its nib file?
Yes, you can use multiple Nib-Files and multiple CellIdentifiers in the TableViewController. Just put your condition before the CellIdentifier. That's the way I've done it.
Some example inside the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method:
First define the variable cell:
UITableViewCell *cell;
Now the if-Block:
if(<condition 1>) {
static NSString *CellIdentifier = #"VideoCell1";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"videoEntryCell" owner:nil options:nil];
for (id currentObject in topLevelObjects){
if([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (UITableViewCell *) currentObject;
break;
}
}
}
// customize your cell here
}
if(<condition 2>) {
static NSString *CellIdentifier = #"VideoCell2";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"videoEntryCell2" owner:nil options:nil];
for (id currentObject in topLevelObjects){
if([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (UITableViewCell *) currentObject;
break;
}
}
}
// customize your cell here
}
and finally:
return cell;
You can repeat the if-Block as often as you want. It's only important that you return a cell, which is not nil.