So I have a custom table view cell which I have designed in its own xib, containing a few labels and images.
I'm trying to update the background colour of one of these labels depending upon the text given to the label & give it rounded edges.
I'm trying this for the edges with the following code, however it does not work and i'm not sure where this code needs to be for it to update each cell as it scrolls.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CardCell";
CardTableViewCell *cell = (CardTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//cell = [[CardTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CardCell"];
cell = [[[NSBundle mainBundle]loadNibNamed:#"CardCell" owner:self options:nil]objectAtIndex:0];
}
// Configure the cell...
NSManagedObject *card = [self.cards objectAtIndex:indexPath.row];
[cell.cardName setText:[card valueForKey:#"name"]];
[cell.type setText:[card valueForKey:#"attribute"]];
[cell.attack setText:[card valueForKey:#"attack"]];
[cell.defense setText:[card valueForKey:#"defense"]];
[cell.species setText:[card valueForKey:#"species"]];
[cell.starLevel setText:[card valueForKey:#"stars"]];
cell.type.layer.cornerRadius = cell.type.bounds.size.height / 8;
UIImage *cardImage = [UIImage imageWithData:[card valueForKey:#"thumb"]];
[cell.cardImage setImage:cardImage];
return (UITableViewCell *)cell;
}
The text and card image display correctly.
The cell has no frame in cellForRowAtIndexPath, therefore the corner radius is not set.
In this case, you should set the corner radius in willDisplayCell.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (yourCellShouldHaveRoundedCorners) {
cell.layer.cornerRadius = cell.bounds.size.height / 8;
}
}
The background color of the label should work in cellForRowAtIndexPath.
Also, I see that you set a lot of properties on the cell in cellForRowAtIndexPath (i.e. type, attack, defense and so on). Since you already have a custom cell, it would be better to create an NSManagedObject property on the cell, and set all these properties on the setter of this object.
This way, you will only have to call cell.managedObject = card and the setter will furher set the other properties.
This approach is more model-oriented and it can save you some code duplication.
Try to use fixed number as cell.type.bounds.size.height won't render to a correct value in cellForRowAt
cell.type.layer.cornerRadius = 10 ;
cell.type.clipsToBounds = YES;
OR add this to cell class
-(void)layoutSubviews
{
self.type.layer.cornerRadius = self.type.bounds.size.height / 8;
}
Regarding color it will work perfectly in cellForRowAt like that
if(yourLogic)
{
cell.type.backgroundColor = [UIColor redColor];
}
else
{
cell.type.backgroundColor = [UIColor greenColor];
}
Related
How to create the following UITableView in a VC with 2 Columns? As UITableView only has one column. Is it possible to do it in StoryBoard? How to add shadow, round the corners and add the blurish borders as in the pic? All help or pointer is greatly appreciated.
Edited
How to set the 2 columns in Objective C? I can't find any help over the net especially for objective C. I think both the columns are UILabel.
As for the rows, do I need to set the Prototype Cell to 3 at Story Board?
The 1st column will have static values: NAME, DATE OF BIRTH, LOCATION. The 2nd column will fetch data from an array [John Doe, 06.03.1991, New York]
Do I create a loop to insert the data?
ANSWER
I followed this link and managed to create 2 custom UILabel columns and insert the columns from NSMutableArray
I can't get the following suggested answer to work, the answer suggested that we create an Empty User Interface and then add a Table View Cell and associate it back to the VC. I can't get it to work.
Mine was just creating the 2 labels at the prototype cell at the TableView and then following the link above.
create a customcell and put 7 UILabel first 4 label gives name basic setting,NAME,DOB,LOCATION than remain 3 label set blank and give tham property in cell.h file
#pragma mark tableview delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [yourdataarray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"yourcustomcellname"];
if (cell == nil) {
// Load the top-level objects from the custom cell XIB.
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"yourcustomcellname" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];
}
id object = [yourdataarray objectAtIndex:indexPath.row];
if ([object isKindOfClass:[NSMutableArray class]]) {
NSMutableArray *Array = (NSMutableArray *)object;
//your cell property use here for fatch like below
[cell.NAME setText:[NSString stringWithFormat:#"%#",[Array objectAtIndex:i]]];//here i=which index your array contain name data
}
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return yourcustomcellheight;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
refer this tutorial for customcell
https://www.appcoda.com/customize-table-view-cells-for-uitableview/
You need to use custom UITableViewCell, it seems the first column is just a label and the second column is a textfield.
In order to add boundary and add corner
myTableViewCell.contentView.layer.borderColor = [[UIColor grayColor] CGColor];
myTableViewCell.contentView.layer.borderWidth = 1;
myTableViewCell.contentView.layer.cornerRadius = 5.0;
myTableViewCell.contentView.clipsToBounds = YES;
myTableViewCell.contentView.layer.masksToBounds = YES;
check following example as a reference to learn how to create Custom UITableViewCell and use.
https://www.appcoda.com/ios-programming-customize-uitableview-storyboard/
These columns you need to design in UITableViewCell. It can be anywhere of your preference, storyboard or xib.
For storyboard your view will be like this.
you need to add tags for all the components you add into the cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
...
...
UILabel *label1 = (UILabel *)[cell viewWithTag:100];
label1.text = #"NAME";
UILabel *label2 = (UILabel *)[cell viewWithTag:200];
label2.text = #"John";
...
...
return cell;
}
The same way if you create xib your custom cell should be like this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
StackTableviewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = (stackTableviewCell*)[[[NSBundle mainBundle] loadNibNamed:#"StackTableviewCell" owner:self options:nil] objectAtIndex:0];
}
...
...
label1.text = #"NAME";
label2.text = #"John";
...
...
}
For cell UI
self.lable1.backgroundColor = [UIColor lightGrayColor];
self.lable1.layer.borderColor = [UIColor colorWithRed:169/255.0 green:169/255.0 blue:169/255.0 alpha:0.8].CGColor;
self.lable1.layer.borderWidth = 1;
self.lable1.layer.cornerRadius = 5;
self.lable1.clipsToBounds = YES;
self.lable1.layer.masksToBounds = YES;
I have a UITableView which I have transformed into horizontal tableview, and a custom UITableViewCell which just has a UIImageView and a UILabel
The problem is, first 5 cells don't show the images, but when I scroll and come back to them, images are shown. No idea what the problem is :(
(picture below, please see the horizontal tableview, ignore the vertical one)
Here's my code in TableViewController Class:
-(void)viewDidLoad
{
//Rotating the tableview angle -PI/2 Rad = -90 Degrees
_friendsTableView.transform= CGAffineTransformMakeRotation(-M_PI_2);
_friendsTableView.translatesAutoresizingMaskIntoConstraints = YES;
CGRect frame = _friendsTableView.frame;
frame.origin.y= _segmentControl.frame.size.height;
frame.origin.x= 0;
frame.size.width = self.view.frame.size.width;
frame.size.height = 105.5;
_friendsTableView.frame= frame;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FriendsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
if (nil == cell) {
cell = [[FriendsTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
if(cell)
{
cell.user = cellsArray_[indexPath.row];
cell.transform =CGAffineTransformMakeRotation(M_PI_2);
}
return cell;
}
Now this is my custom cell class code where I set the image and label (_user is a property, so this setter method gets called automatically from cell.user):
-(void)setUser
{
_profileImageView.layer.cornerRadius = _profileImageView.frame.size.width/2;
_user = user;
_nameLabel.text = #"Hello";
[_profileImageView setImage:[UIImage imageNamed:#"placeholder_image"]];
}
Why dont you use Collection View controller instead. Transforming Tableview controller seems not good.
In your code your are not calling your setUser method.
For Custom table view cell you can add following code in
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:strID];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyCustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
}
For my experience this is strictly related to the reusability of the Cells, i had a similar problem once, my solution is before assigning something to an IBOulet, make sure to have it empty, after that, assign it and it should work.
I want to change the color of a UITableView cell. I have this code but it doesn't work. Can someone explain to me why and what I should change?
[_myTableView cellForRowAtIndexPath : [NSIndexPath indexPathForItem:myIndexAsInt inSection:0]].contentView.backgroundColor = [UIColor greenColor];
To change the color of a standard UITableViewCell you need to do that by overriding the UITableViewDelegate method tableView:willDispayCell:forRowAtIndexPath: like so:
- (void)tableView:(UITableView *)tableView willDispayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.contentView.backgroundColor = color;
}
If your cell has custom content you might want to have a slightly different implementation.
to set the 3rd cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 2)
{
cell.contentView.backgroundColor = [UIColor redColor];
}
return cell;
}
The line of code itself is ok syntacticaly.
Some things cannot be verified from my side. Please put a breakpoint on that line and run it.
0) By putting a breakpoint there, and seeing the system stop there, you actually check that that line is executed.
1) If step 0 was ok, check that you actually have an instance of table view (it must NOT be nil, maybe if you are using nibs, you forgot to create an IBoutlet).
2) Make sure the tableView has proper delegate and datasource. (usually the ViewController where those things you mention are handled...)
3) check that you are passing a proper type and proper value for the myIndexAsInt argument. It should be of NSInteger type and should be equal 2.
4) If all 3 above are ok, perhaps you are calling it from a wrong place.
Let us know how it went.
You can have an variable to hold the index position. So after your didSelectRowAtIndexPath delegate called just set the index position in that variable and reload the table. Use a condition in cellForRowAtIndexPath datasource method to check for index position and now set the background colour for that specific cell.
in .h file:
NSInteger indexPos;
in didSelectRowAtIndexPath delegate:
indexPos = indexPath.row;
in cellForRowAtIndexPath:
if (indexPath.row == indexPos) {
cell.backgroundColor = [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f];
} else {
cell.backgroundColor = [UIColor colorWithRed:0/255.0f green:0/255.0f blue:0/255.0f alpha:1.0f];
}
I created several cells with Interface Builder, and I'm using them to fill a UITableView. In other words, I have 3 classes for 3 different kinds of cell, and an other view which contains a UITableView.
- My UITableView containing different kinds of cells :
Here's my problem :
On the iPhone emulator, it looks great. But on the iPad emulator, the custom cells width is fixed. The UITableView width fits to the screen width, so it's good, but the UITableViewCells does not fit to the UITableView. I want to force the custom UITableViewCells to take the UITableView width.
Is there anything to do in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPathmethod, where I instanciate my custom cells ?
Or do I have to write a thing like self.fitToParent; in the custom cells header file ?
EDIT (schema) :
EDIT 2 (cellForRowAtIndexPath method) :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifierType1 = #"cellType1";
static NSString *cellIdentifierType2 = #"cellType2";
NSString *currentObjectId = [[myTab objectAtIndex:indexPath.row] type];
// Cell type 1
if ([currentObjectId isEqualToString:type1])
{
CelluleType1 *celluleType1 = (CelluleType1 *)[tableView dequeueReusableCellWithIdentifier:cellIdentifierType1];
if(celluleType1 == nil)
celluleType1 = [[CelluleType1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierType1];
celluleType1.lblAuteur.text = #"Type1";
return celluleType1;
}
// Cell type 2
else if ([currentObjectId isEqualToString:type2])
{
CelluleType2 *celluleType2 = (CelluleType2 *)[tableViewdequeueReusableCellWithIdentifier:cellIdentifierType2];
if(celluleType2 == nil)
celluleType2 = [[CelluleType2 alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifierType2];
celluleType2.lblAuteur.text = #"Type2";
return celluleType2;
}
else
return nil;
}
}
I think uitableviewcell's width is the same as the tableview's width.You can try to set cell's background color to test it. cell.backgroundColor = [UIColor redColor] ;
You should create a class which inherit from UITableViewCell and override it's method - (void)layoutSubviews , adjust your content's frame there.
I resolved my problem using the following code in each custom cell class. It's not very clean, but I can't spend one more day on this issue...
- (void)layoutSubviews
{
CGRect contentViewFrame = self.contentView.frame;
contentViewFrame.size.width = myTableView.bounds.size.width;
self.contentView.frame = contentViewFrame;
}
Thank you for your help KudoCC.
- (void)awakeFromNib {
[super awakeFromNib];
// anything you write in this section is taken with respect to default frame of width 320.
}
awakeFromNib is called when [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; is processed- anything you write in section is taken with respect to default frame of width 320.
You need to make another custom function and call it after cell gets initialized.
For eg:-
#implementation CheckinTableViewCell{
UILabel *NameLabel;
UILabel *rollLabel;
}
- (void)awakeFromNib {
[super awakeFromNib];
NameLabel = [[UILabel alloc] initWithFrame:CGRectZero];
rollLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[self.contentView addSubview:NameLabel];
[self.contentView addSubview:rollLabel];
}
-(void) bindView{
NameLabel.frame = CGRectMake(10, 10, self.contentView.frame.size.width-20, 20);
rollLabel.frame = CGRectMake(10, 30, NameLabel.frame.size.width, 20);
}
and call this function in tableview cellForRowAtIndex:-
-(UITableViewCell*) tableView: (UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
CheckinTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell ==nil){
cell = [[CheckinTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.name = #"Harry";
cell.rollno = #"123456";
[cell bindView];
return cell;
}
i want to costumize the static cells in my storyboard table by drawing them with draw-rect, but how do i loop over all the cells and draw the rect?
I have read this tutorial but it only covers prototype cells:
http://www.raywenderlich.com/32283/core-graphics-tutorial-lines-rectangles-and-gradients
Assuming i have a draw rect method, how do i loop the static cells and apply it ?
EDIT 1:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// START NEW
if (![cell.backgroundView isKindOfClass:[CostumCellBackground class]]) {
cell.backgroundView = [[CostumCellBackground alloc] init];
}
if (![cell.selectedBackgroundView isKindOfClass:[CostumCellBackground class]]) {
cell.selectedBackgroundView = [[CostumCellBackground alloc] init];
}
// END NEW
cell.textLabel.backgroundColor = [UIColor clearColor]; // NEW
return cell;
}
If i use this in my Table View Controller, this is from the turtorial, i removed the parts that assigned value to the cell, since they are static.
This does not work becouse UITableViewCell has to return a value, and for some reason it does not.
I did assign the ID "Cell" to the rows, as he does in the tutorial
Try creating a custom table cell and doing this:
-(void)awakeFromNib
{
self.backgroundView = [[CostumCellBackground alloc] init];
self.selectedBackgroundView = [[CostumCellBackground alloc] init];
}
Then in your tableview controller, since your cells are static, you can assign them as IBOutlets and do something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *returnCell;
switch(indexPath.row)
{
case 0: returnCell = self.staticCell0;
break;
case 1: returnCell = self.staticCell1;
break;
//etc
}
return returnCell;
}