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.
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;
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];
}
I'm having some troubles with auto-resizing table view cells. I've been able to resize a cell's label based on its amount of text but I'm unable to adjust the cell height accordingly. Here's some code:
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
_cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (_cell == nil)
{
_cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
PFObject *object = [_postsArray objectAtIndex:indexPath.row];
NSString *nameString = [object objectForKey:#"Name"];
_cell.cellLabel.text = [NSString stringWithFormat:#"Posted by %#", nameString];
_cell.cellPostLabel.text = [NSString stringWithFormat:#" %#", [object objectForKey:#"PostedDream"]];
[_cell.cellPostLabel sizeToFit];
[tableView setAutoresizesSubviews:YES];
NSLog(#"cell post label height: %f", _cell.cellPostLabel.frame.size.height);
return _cell;
}
Things to note are that I am using a custom table view cell called TableViewCell *cell subclassed from UITableViewCell and the cell and its labels were added through IB.
The label that's being adjusted is cellPostLabel and it adjusts perfectly depending on the amount of text, but it gets cut off due to the cell not adjusting as well.
I also tried calling [self.tableView setAutoresizesSubviews:YES]; and
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight; in viewDidAppear: but still nothing. Any suggestions would be appreciated.
Cell height is determined by heightForRowAtIndexPath method.
You can implement that method on your viewcontroller and return height you prefer.
If your cell should have different height you should implement that method and return different value each cells. Or not just return static value or set tableview's property rowHeight, in this case you don't need to implement that method.
I am expanding a UITableView cell on click.When the cell expands I have to load a UIView into it.My problen is that I am able to see the UIView on few occasions and sometimes it doesn't display ? The UIView is to be loaded in each and every expanded cell.
Expansion is done like this:-
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat kExpandedCellHeight =300;
CGFloat normalCellHeight = 94;
if ([self.expandedCells containsObject:indexPath]) {
return kExpandedCellHeight;
}else{
return normalCellHeight;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Cell";
ListCell *cell =(ListCell*) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
NSArray *nibs = [[NSBundle mainBundle]loadNibNamed:#"ListCell" owner:self options:nil];
cell = nibs[0];
}
cell.Name.text = [[nameArray objectAtIndex:indexPath.row]valueForKey:#"opName"];
if (isExpanded) {
backgroundView = [[UIView alloc]initWithFrame:CGRectMake(0, 95, 320,205)];
[backgroundView setBackgroundColor:[UIColor colorWithRed:(235/255) green:(235/255) blue:(235/255) alpha:0.1]];
[cell.contentView addSubview:backgroundView];
container = [[UIView alloc]initWithFrame:CGRectMake(40, 67, 240, 120)];
container.backgroundColor = [UIColor whiteColor];
//I am adding buttons to this scrollview after webservice response,once buttons are loaded I am trying to load the above container on the background view.
container_scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(20, 5, 220, 110)];
[container_scrollView setBackgroundColor:[UIColor whiteColor]];
[container addSubview:container_scrollView];
}
return cell;
}
Now I do get response from webservice.Buttons are added as well.However I can see the container view loaded sometimes and sometimes it doesn't show.What must be the reason?What is causing this behaviour?
This is how I load the container onto background view.
//After container is loaded with buttons.
if(backgroundView){
[backgroundView addsubView:container];
}
Declaration stuff:
#interface ListViewController ()
{
UIView *backgroundView;//Used in expanded cell.
UIView *container;
BOOL isExpanded; //I set this to NO in viewDidLoad initially.
UIScrollView *container_scrollView;
}
You should consider having two different cells on your storyboard or two xib files, each with its correspoding cellidentifier. One will be your normal cell and the other the expanded cell. Then whenever a user taps on one normal cell you should 'replace'(redraw) that specific cell with your second type cell (an expanded cell).
UPDATE
For performing the update of the cells you could use any of these methods. more here
reloadData
reloadRowsAtIndexPaths:withRowAnimation:
reloadSections:withRowAnimation:
Those will cause that some of your Table View Data Source delegate methods get called again, you should then use some logic to decide which kind of cell to draw. A quick draft:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier;
// Here you should implement your custom logic to check if you want a basic or expanded cell.
if (IWantBasicCell) {
cellIdentifier = #"basicCell";
} else {
cellIdentifier = #"expandedCell"
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
[cell myCustomLoadInformationMethod:myCustomData];
return cell;
}
I'm trying to add as subview into a section in UITableView, It looks like the code is correct, the it doesn't show anything, just blank section. Here's the code that I use:
- (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] autorelease];
}
if(indexPath.section==0){
cell.textLabel.text =#"<>";
}else if(indexPath.section==1){
if(indexPath.row==1){
cell.frame =CGRectMake(0,0, 100, 100);
[cell.contentView addSubview:page.view];
}
} else if(indexPath.section==2){
}
// Configure the cell.
return cell;
}
Thanx in advance..
One of the problems is that you are trying to change the height of the cell. If you want to do so, in addition to changing its frame, you must also implement tableView:heightForRowAtIndexPath: and return appropriate values for each row. If page is properly loaded (assuming it's a view controller), you can add the view as a subview. Make sure its frame falls within the bounds of the cell.
Attaching the view
Since dPage is a view controller, you will have to declare page as an ivar of class dPage and then do this in viewDidAppear:,
page = [[dPage alloc] initWithNibName:"page" bundle:nil];
and tableView:cellForRowAtIndexPath: remains unchanged.