Customized UITableViewCell reuse with childviewcontroller issue - ios

I have create a UITableView With a Customized TableViewCell,
#import <UIKit/UIKit.h>
#import "Equipment.h"
#import "MCStepperViewController.h"
#class EquipmentCell;
#protocol EquipmentCellDelegate <NSObject>
- (void)EquipmentCell:(EquipmentCell *)cell didChangeStepperValue:(int)stepperValue indexPath:(NSIndexPath*)indexPath;
#end
#interface EquipmentCell : UITableViewCell <MCStepperDelegate>
#property (nonatomic, strong) UIImageView* eqiupmentImage;
#property (nonatomic, strong) UILabel* Title;
#property (nonatomic, strong) UILabel* details;
#property (nonatomic, strong) UILabel* prices;
#property (nonatomic, strong) MCStepperViewController* stepper;
#property (nonatomic, weak) id <EquipmentCellDelegate> delegate;
#property (nonatomic, assign) NSIndexPath* indexPath;
-(void)setContent:(Equipment*)equip;
-(void)setAmount:(int)eq_amount;
#end
The customized cell owns a stepperview controller, and I add the stepperViewController.view to the content view of the cell.
The stepperViewController has a textField and two buttons as strong properties.
The confusing part is, when I scroll the table view, the table cells are ready for reuse process.
The property views of the cell works well, but the view of stepperViewController, which is the subview of the contentView, is becoming duplicate.
Although I have set cell.stepper.view.textField to the right value, but it still doesn't work.
Is there any good solution? I don't think disable reusability is a good attempt.
Thank you very much!
EDIT:
The cellForRowAtIndexPath method:
else if (tableView == _subTable)
{
EquipmentCell *cell = [tableView dequeueReusableCellWithIdentifier:#"detailTable" forIndexPath:indexPath ];
if(!cell)
{
cell = [[EquipmentCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"detailTable"];
}
cell.indexPath = indexPath;
Equipment* item = [[[_goodsList objectAtIndex:indexPath.section] objectForKey:#"data"] objectAtIndex:indexPath.row];
cell.delegate = self;
[cell setContent:item];
if (countDic) {
if ([countDic objectForKey:[NSString stringWithFormat:#"%lu", (indexPath.section*100)+(indexPath.row)]]) {
[cell setAmount:(int)[[countDic objectForKey:[NSString stringWithFormat:#"%lu", (indexPath.section*100)+(indexPath.row)]] integerValue]];
}
else
{
[cell setAmount:0];
}
}
return cell;
}
I tried to assign the textfield.text in cell class, but is doesn't work.
- (void)setAmount:(int)eq_amount
{
_stepper.amount = eq_amount;
_stepper.amountText.text = [NSString stringWithFormat:#"%d", eq_amount];
if (eq_amount == self.stepper.min) {
_stepper.minusButton.hidden = YES;
_stepper.amountText.hidden = YES;
}
}

Check where you add your stepperViewController.view to the content view of the cell.
You want to support view recycling for your tableview cell. So as soon as your cell1 is not visible anymore and data 2 needs a cell (cellForRowAtIndexPath gets called), this reused cell will be cell 1. Instead of data1 cell1 now displays data2. If you add the stepperViewController.view in the cellForRowAtIndexPath function, there will be the view added for data1. now if cell1 isn't visible anymore and should be used for data2 you should check if you add the stepperViewController.view again.
Instead of simply adding the view, you could check if there is already a stepperViewController.view in you cell's subviews and remove or reuse it.

Related

UILabel displaying (null) in custom UItableviewcell

I can't figure out why my UILabels in my custom TableViewCell are nil in CellForRowAtIndexPath. I used the same method as I did for a previous TableView in another view Controller. Here's what I already checked:
Cell Style is Custom
Cell has a unique identifier "profilecell"
Cell's class is of the desired custom type
data source and delegated are connected to the View Controller
Each of the 5 buttons/labels is connected to its respective property in the custom class
Dynamic Prototypes is selected
I am able to change the background color of the cell and populate the textLabel.text -- it's just my UILabels that aren't filled.
Here is CellForRowAtIndexPath. It's the exact same method as my other TableVC, which works. Also, I don't need to actually reuse this custom cell, should I be using a different method?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifierProfile = #"profilecell";
ProfileSection0TableViewCell *profilecell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierProfile];
if (profilecell == nil) {
profilecell = [[ProfileSection0TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifierProfile];
}
if (indexPath.section == 0) {
[profilecell setBackgroundColor:[UIColor colorWithRed:54/255.0f green:61/255.0f blue:147/255.0f alpha:1.0f]];
if (indexPath.row == 0) {
profilecell.labelName.text = _userProfile.fullName;
NSString *test = [NSString stringWithFormat:#"%#", profilecell.labelName.text];
NSLog(#"text %#", test); //shows that label is (null)
profilecell.labelName.textColor = [UIColor whiteColor];
//profilecell.labelSpecialty.text = _userProfile.specialty;
//profilecell.labelSpecialty.textColor = [UIColor whiteColor];
}
}
return profilecell;
}
Thanks so much in advance.
.h file:
#interface ProfileSection0TableViewCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UILabel* labelName;
#property (nonatomic, weak) IBOutlet UILabel* labelSpecialty;
#property (nonatomic, weak ) IBOutlet UILabel* labelCurrentRole;
#property (nonatomic, weak) IBOutlet UILabel* labelPosition;
#property (nonatomic, weak) IBOutlet UIButton* facePicture;
#end
.m file:
#implementation ProfileSection0TableViewCell
#synthesize labelName, labelSpecialty, labelPosition, facePicture, labelCurrentRole;
#end
EDIT:
It looks like ProfileSection0TableViewCell is allocated properly, but the member vars inside the cell are nil. And in outlets, here are the connections:
facePicture - Button
labelName- UILabel "person"
labelPosition - UILabel "position"
List item - UILabel "specialty"
labelCurrentRole - UILabel titled school
Either _userProfile.fullName is nil or profilecell.labelName is nil
If you made the cell in interface builder, did you hook up the outlet to labelName correctly?

Prototype cell won't show content

I have designed a cell in storyboard, then created a custom UITableViewCell subclass (BasicCell) and assigned it to it. Also set the proper identifiers. I created outlets of the custom cell in that class. Then in my UITableViewController subclass (where I have two types of prototype cells), the cells content won't show up. What am I doing wrong?
BasicCell.h
#interface BasicCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UILabel *scorevalue;
#property (strong, nonatomic) IBOutlet UILabel *avgvalue;
#property (strong, nonatomic) IBOutlet UILabel *rankvalue;
#property (strong, nonatomic) IBOutlet UILabel *scorelabel;
#property (strong, nonatomic) IBOutlet UILabel *categorylabel;
#property (strong, nonatomic) IBOutlet UILabel *ranklabel;
#end
TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifierBasic = #"basic";
static NSString *CellIdentifierDetailed = #"detailed";
UITableViewCell *cell;
if(indexPath.row==0){
// Create first cell
cell = [[BasicCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierBasic];
}
else{
// Create all others
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierDetailed forIndexPath:indexPath];
}
// Configure the cell...
switch ([indexPath row])
{
case 0:
{
BasicCell *basicCell = (BasicCell *)cell;
basicCell.scorelabel.text = #"test";
basicCell.categorylabel.text = #"test";
basicCell.ranklabel.text = #"test";
basicCell.scorevalue.text = #"test";
basicCell.avgvalue.text = #"test";
basicCell.rankvalue.text = #"test";
}
}
In your storyboard,
Create two prototype cell.
Change one of your prototype cell's custom class. Set it BasicCell.
Make sure that you set appropriate cell identifier for each type of cell.
Don't alloc init if it's indexPath.row == 0 but dequeue with appropriate identifier.
It should work.
Note: You should declare your IBOutlets as weak not as strong. Cell's view has already strong pointer to them. You don't have to own them.

How to get the multiple selected CollectionViewCell from the UICollectionView?

I create a xib file and add a Collection View Cell. I add the progress bar in header file of cell like the following code.
#import <UIKit/UIKit.h>
#import "MobileVLCKit/VLCMediaThumbnailer.h"
#interface AITFileCell_grid : UICollectionViewCell <VLCMediaThumbnailerDelegate>
#property (strong, nonatomic) IBOutlet UIImageView *fileIcon;
#property (strong, nonatomic) IBOutlet UILabel *fileName;
#property (strong, nonatomic) IBOutlet UILabel *fileSize;
#property (strong, nonatomic) NSURL *filePath ;
+ (NSString *)reuseIdentifier ;
#end
#interface AITFileCell_grid()
{
BOOL fetching ;
#public
UIProgressView *dlProgress;
UILabel *dlProgressLabel;
}
#end
I also create another xib file and add the Collection View for loading Collection View Cell.
I want to selected multiple file and hide the progress bar on each cell by button.
But I can not get the cell when I click the delete button by following code.
- (IBAction) buttonCancel:(id)sender {
if(self.collectionView.indexPathsForSelectedItems > 0){
for(NSIndexPath *indexPath in self.collectionView.indexPathsForSelectedItems){
AITFileCell_grid *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:#"AITFileCell_grid" forIndexPath:indexPath];
//Hide the progress bar
cell->dlProgressLabel.text = #"0%";
cell->dlProgress.hidden = YES;
cell->dlProgressLabel.hidden = YES;
}
}
[self setEditing:NO animated:YES];
}
I set the breakpoint to the cell->dlProgressLabel.text = #"0%"; , it show the nil in the log...and the progress bar didn't change anything.
But I can set the value to cell->dlProgressLabel.text and set value to cell->dlProgress in NSTimer.
Why the cell define in the UIButton seems not be efficient ?...
Can someone help and teach me how to solve ?
You are dequeuing Cell by doing
AITFileCell_grid *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:#"AITFileCell_grid" forIndexPath:indexPath];
which could be different from what you have been selected, instead get the selected cell from the collectionView
AITFileCell_grid *cell = [self.collectionView cellForItemAtIndexPath: indexPath]

Custom UITableViewCell Class Issue

I've read quite a few tutorials online about how to create a custom cell subclass, but I'm still a little confused. When I try to follow the instructions found in this question, I end up with errors that the tableView is not a valid property for the object of ViewController.
I've created a new subclass of UITableViewCell, called CustomBookClass. I've hooked up the properties with my CustomBookClass.h file.
#import <UIKit/UIKit.h>
#interface CustomBookCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *bookImage;
#property (weak, nonatomic) IBOutlet UILabel *bookTitle;
#property (weak, nonatomic) IBOutlet UILabel *dateAdded;
#end
I then go into my ViewController.m file to edit the viewDidLoad method.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView.delegate = self];
[self.tableView.dataSource=self];
[self.tableView registerClass:[CustomBookCell class]forCellReuseIdentifier:#"Custom
Cell"];
}
I get an error on the tableView, saying the property doesn't exist, even though in the ViewController.h file, I'm including the table view.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource>
#end
I'm sure I'm missing something really obvious here, as this is my first time trying this. Can anyone help me out? Thanks!
UIViewController does not have that property. Even if you assign the Delegate and DataSource protocols to it. There are a couple of things you can do however.
Link the table view to the ViewController yourself. That means, create a property/outlet called tableView.
Inherit from UITableViewController instead of UIViewController.
Both should work.
Edit: Oh and the lines:
[self.tableView.delegate = self];
[self.tableView.dataSource=self];
don't make sense. They should be either:
self.tableView.delegate = self; and self.tableView.dataSource = self;
Or [self.tableView setDelegate:self]; and [self.tableView setDataSource:self]
with 1 being preferred. (Edit: option #2 was actually incorrect code, my bad.)
No need to set delegate and datasource in TableViewCell class
simple make a property and synthesize your table view item
#property (weak, nonatomic) IBOutlet UIImageView *bookImage;
#property (weak, nonatomic) IBOutlet UILabel *bookTitle;
#property (weak, nonatomic) IBOutlet UILabel *dateAdded;
now import your cell class in your tableView controller class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
//If you are using xib for representing your UI then add a nib file.
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.bookTitle.text = [tableData objectAtIndex:indexPath.row];
cell.bookImage.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.dateAdded.text = [prepTime objectAtIndex:indexPath.row];
return cell;
}
for more detail check this link

Data is disappearing from UITableView

I am building an iOS app with a custom tab bar at the top. When i click on the home icon, I want it to show a tableview directly below the tab bar. Currently my code does just that, however the data doesnt show correctly. If I limit my Cells to 4 or less (in the numberFoRowsInSection), the data will show, if i have like say 15 cells, the data shows for a split second and then it disappears. I have been looking at tutorials all over the place and everything seems to be correct, the data will show correctly in a stand alone view(like i created a similar to a singleview application in the story board and made that the initial view). I dont know where i am wrong. Below is my code in implementation file of the tableviewContoller class:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 4;//this works... but change to 15 it doesnt work
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
PrayerCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
if (cell == nil) {
NSLog(#"cell is Nil"); //never hits this
cell = [[PrayerCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CustomCell"];
}
//the data showing is the correct data that i want to see
cell.dName.text = [[news objectAtIndex:indexPath.row] objectForKey:#"displayname"];
cell.priority.text = [[news objectAtIndex:indexPath.row]objectForKey:#"priority"];
cell.dateTime.text = [[news objectAtIndex:indexPath.row] objectForKey:#"datetime"];
cell.numPraying.text = #"2 praying";
cell.requestPreview.text = [[news objectAtIndex:indexPath.row] objectForKey:#"request"];
NSLog(#"created cell") //verify cell was made
return cell;
}
Here is my PrayerCell.H file
#interface PrayerCell : UITableViewCell
#property (weak, nonatomic)IBOutlet UILabel *requestPreview;
#property (weak, nonatomic)IBOutlet UILabel *dName;
#property (weak, nonatomic)IBOutlet UILabel *dateTime;
#property (weak, nonatomic)IBOutlet UILabel *numPraying;
#property (weak, nonatomic)IBOutlet UILabel *priority;
#end
I made no Changes to the prayerCell.M file
if you need me to post any other code blocks/screenshots please let me know.
The cell should not be an ivar, it should be a local variable. You also need to dequeue the cell in your tableView:cellForRowAtIndexPath: method:
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];

Resources