Move UILabel on custom cell when entering editing - ios

I've got 3 uilabels added to a uitableview cell. The problem that I am running into is when I swipe to delete, my UILabel on the right side of the cell doesn't move so the delete button and the UILabel are overlapping each other. I've posted some of my code below.
I developed my layout using storyboard, so from what I am reading, frames aren't going to help.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *baseTableCellIdentifier = #"baseCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:baseTableCellIdentifier];
BaseInfo *infoAtIndex = [[[DataClass getInstance] allItems] objectAtIndex:[indexPath row]];
baseName = (UILabel *)[cell viewWithTag:1];
baseICAO = (UILabel *)[cell viewWithTag:2];
baseTime = (UILabel *)[cell viewWithTag:3];
[cell.contentView addSubview:baseName];
[cell.contentView addSubview:baseICAO];
[cell.contentView addSubview:baseTime];
[baseName setText:[infoAtIndex name]];
[baseICAO setText:[infoAtIndex icao]];
baseTimeZome = [NSTimeZone timeZoneWithName:[infoAtIndex timeZone]];
[baseDate setDateFormat:#"HH:mm"];
[baseDate setTimeZone:baseTimeZome];
NSString *baseTimeString = [baseDate stringFromDate:[NSDate date]];
[baseTime setFont:[UIFont boldSystemFontOfSize:20]];
[baseTime setText:baseTimeString] ;
return cell;
}
-(void)setEditing:(BOOL)editing animated:(BOOL)animated{
if (editing) {
//no idea what to put here
}else{
}
}

In your UITableViewCell subclass override setEditing:animated: and perform there any layout change. As the commenter says, you may not need to do that setting proper values for your label's autoresizingMask.

You should create a cell subclass. Then you can implement setEditing:animated: to modify the subviews frames.

Related

Constraints not working when using viewWithTag to get labels inside UITableviewCell

I really can't get my head around why this isn't working properly.
I have a TableViewController with dynamic prototypes. I put 4 labels in a prototype named "InfoCell", and gave them constraints.
If i run the app with the following cellForRowAtIndexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"InfoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
return cell;
}
what I get is this. Everything looks fine 'til now
I did this just to check that the labels were being displayed in the right place. The page is supposed to show 2 cells, so everything looks fine.
Now, the problems start when I try to get a reference to the labels in order to change the text. Even without actually changing the text, if my code looks like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"InfoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:10];
UILabel *surnameLabel = (UILabel *)[cell viewWithTag:20];
UILabel *roleLabel = (UILabel *)[cell viewWithTag:30];
UILabel *spouseNameLabel = (UILabel *)[cell viewWithTag:40];
[cell addSubview:nameLabel];
[cell addSubview:surnameLabel];
[cell addSubview:roleLabel];
[cell addSubview:spouseNameLabel];
return cell;
}
I get this. Labels' positions went nuts
I tried, for example, to change the frame of each label programmatically,
nameLabel.frame = CGRectMake(15.0, 50.0, 120.0, 20.0)
but it just doesn't do anything, I suppose because auto-layout is enabled... but I'm too far into the project to disable auto-layout. Plus I've seen the use of viewWithTag as I wrote above working without the need to re-locate the labels programmatically, so it bugs me not to know what's really happening there!
Remember that when you have constraints added on any of the UI object, you can't change the frame of that object by changing its CGRect. In fact, you should change its constraint value.
Now the problem in your code is ,
[cell addSubview:nameLabel];
[cell addSubview:surnameLabel];
[cell addSubview:roleLabel];
[cell addSubview:spouseNameLabel];
above 4 lines. When you have added a UILabel in storyboard, why are you adding them again by using addSubview method ? Remove above 4 lines, and to set text on your UILabel , you already have a reference which you are accessing by using their tag values. So your method should looks like as below.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"InfoCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *nameLabel = (UILabel *)[cell viewWithTag:10];
UILabel *surnameLabel = (UILabel *)[cell viewWithTag:20];
UILabel *roleLabel = (UILabel *)[cell viewWithTag:30];
UILabel *spouseNameLabel = (UILabel *)[cell viewWithTag:40];
nameLabel.text = #"";
surnameLabel.text = #"";
roleLabel.text = #"";
spouseNameLabel.text = #"";
return cell;
}

UISlider not sliding in prototype cell

I have designed a prototype cell in a Storyboard's view controller, but unfortunately the UISlider in the cell is not sliding.
Note:- Autolayout is enabled for this storyboard.
Design:-
Here is code:- to render the cell in UITableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if(indexPath.row!=self.arrSelectRecipientsImages.count-1 )
{
cell = [tableView dequeueReusableCellWithIdentifier:#"selectReciptenceTabCell" forIndexPath:indexPath];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:#"selectNearbyTabCell" forIndexPath:indexPath];
UISlider *sliderNearby = (UISlider *)[cell.contentView viewWithTag:199];
lblDistance = (UILabel *)[cell.contentView viewWithTag:190];
sliderNearby.userInteractionEnabled = YES;
[sliderNearby setThumbImage:[UIImage imageNamed:#"NearbyCircle"] forState:UIControlStateNormal];
[sliderNearby addTarget:self action:#selector(sliderNearbyAction:) forControlEvents:UIControlEventValueChanged];
}
return cell;
}
The code is working fine I think.
Also no need to set user interaction.
Here is the example code may you get help form it. It is working fine with autolayout.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
UILabel *lblTitle = (UILabel *)[cell viewWithTag:100];
lblTitle.text = #"Hi";
UISlider *slider = (UISlider *)[cell viewWithTag:101];
slider.value = 0.2;
slider.tag = indexPath.row;
[slider addTarget:self action:#selector(sliderNearbyAction:) forControlEvents:UIControlEventValueChanged];
return cell;
}
- (void)sliderNearbyAction:(UISlider *)sender{
NSLog(#"Slider %ld Value : %.2f",(long)sender.tag, sender.value);
}
OUTPUT with Log :
Autolayout Screenshot :
Well, the problem was very silly, I have not provided height for cell in different index-path.That's why the last cell i.e the slider cell was showing but it's height was 30, so any tap or gesture outside that region was not responding.
Maybe the issue was in isUserInteractionEnabled. If you have any interactable elements as subviews of cell (not of contentView), you need to set
cell.contentView.isUserInteractionEnabled = false
for the cell.

UILabel in my custom UITableViewCell doesn't change text properly

I have a custom UITableViewCell inside it I have a label that shows the ammount of licks ,
when i drawing the cell everything is fine , however when I'm trying to change the label text it overlaps on its self (and it is very sad tbh).
I tried to remove and add it again , also tried to set needsDisplay and it didn't help me :(
here is my code :
in DrawLabel method
//we will start from the labels: licks and comments
_licksLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 5, self.frame.size.width, 40)];
[_licksLabel setText:[NSString stringWithFormat:#"%# %#",[_dict objectForKey:#"loves"],LocalizedString(#"licks")]];
[_licksLabel setFont:[UIFont fontWithName:FONT_REGULAR size:15]];
[_licksLabel sizeToFit];
[_licksLabel setTextColor:UIColorFromRGB(grey4)];
[self addSubview:_licksLabel];
when I do want to change the label's text here in another method
- (void)meLike
{
if ([[_dict objectForKey:#"self_loved"]integerValue]>0)
{
// return;
}
[_licksLabel removeFromSuperview];
[FeedAPI loveFeedWithId:[_dict objectForKey:#"id"]];
[_dict setValue:[NSNumber numberWithInt:1] forKeyPath:#"self_loved"];
[_dict setValue:[NSNumber numberWithInt:[[_dict objectForKey:#"loves"]integerValue]+1] forKeyPath:#"loves"];
[_licksLabel setText:[NSString stringWithFormat:#"%# %#",[_dict objectForKey:#"loves"],LocalizedString(#"licks")]];
[_licksButton setImage:[UIImage imageNamed:#"ic_lick_on.png"] forState:UIControlStateNormal];
[self setNeedsDisplay];
[super setNeedsDisplay];
[self addSubview:_licksLabel];
}
I find a little mess in your code. I Whould do like the following:
Use interface builder to add a UITableViewCell prototype to your table
assign (via interface builder) a reuse identifier (for example "cell")
inside this UITableViewCell add a UILabel (via interface) and place it wherever you like
assign a tag to the UILabel (for example 1)
After this setup you need to implement the table rows.
Here's an example
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
UILabel *name = (UILabel *) [self.tableView viewWithTag:1];
name.text = #"whateveryouwant;
return cell;
}
Okay thanks for help to every1 i have solved the issue
the solution was to reload the tableview data .

Set a label in a cell that is controlled by a stepper - objective c

Hi I have a UITableView and I am dymanically inserting cells into it that contain a UIStepper and a UILabel. The UILabel shows the value of the UIStepper.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(!cell)
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
[cell.textLabel setText:[self.myarray objectAtIndex:indexPath.row]];
UIStepper *stepper = [[UIStepper alloc]init];
UILabel *label = [[UILabel alloc]init];
label.text = [NSString stringWithFormat:#"%.f", stepper.value];
[cell addSubview:stepper];
[cell addSubview:label];
[stepper addTarget:self action:#selector(incrementStepper:) forControlEvents:UIControlEventValueChanged];
return cell;
}
I have removed some of the above lines that do the formatting for clarities sake but this works and everything is ok.
-(void)incrementSkillStepper:(id)sender
{
UIStepper *stepper = (UIStepper*)sender;
//set the label that is in the same cell as the stepper with index stepper.value.
}
When I click the stepper in the specific cell I want the label in the same cell to increment, but my problem is in which the way that addtarget works - I can only send the sender which in this case is the stepper to the event which means it doesnt have access to the dynamically created label. Does anybody know how I can set the text of the label from the incrementStepper delegate method?
Call [sender superview] to get the cell that it's in,
-(void)incrementSkillStepper:(id)sender
{
UIStepper *stepper = (UIStepper*)sender;
UITableViewCell* cell = [stepper superview];
UIView* subview = [[cell subviews] lastObject]; // Make sure your label *is* the last object you added.
if ([subview isKindOfClass:[UILabel class]]) {
// do what you want
}
}
you can also loop thru the [cell.contentView subviews] array, and get the label you need, better give the label a tag value, and use viewWithTag
You can set tag to UIStepper as indexPath.row and set tag to label as indexPath.row+999.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIStepper *stepper = [[UIStepper alloc]init];
stepper.tag = indexPath.row;
UILabel *label = [[UILabel alloc]init];
label.tag = indexPAth.row + 999;
//......
}
Now in delegate method of UIStepper, you can find label in that cell like this
-(void)incrementSkillStepper:(id)sender
{
UIStepper *stepper = (UIStepper*)sender;
UILabel *label = (UILabel *)[self.view viewWithTag:sender.tag + 999];
//now this is same label as you want. Now you can change the value of label as you want
}
You should update the model with the value of the stepper, and then set the label's value based on that value in the model. You should give the stepper a tag in cellForRowAtIndexPath that's equal to the indexPath.row, and in the stepper's action method, set the value of a property in your model to the stepper's value. Then, reload the row at that same indexPath.
(void)incrementSkillStepper:(UIStepper *)sender {
NSInteger row = sender.tag;
[self.theData[row] setObject:#(sender.value) forKey:#"stepperValue"];
[self.tableView reloadRowsAtIndexPaths: #[row] withRowAnimation:UITableViewRowAnimationNone];
}
In cellForRowAtIndexPath, you would have something like this to populate the label:
UILabel *label = [[UILabel alloc]init];
label.text = [NSString stringWithFormat:#"%#", self.theData[indexPath.row][#"stepperValue"]];
In this example, I'm assuming you have an array of dictionaries (theData) that has all the data you need to populate the cells. One of the dictionary keys, "stepperValue" would be used to store the stepper value as an NSNumber.

Change the height dynamically on UITableViewCell's based on 1 label?

How can I scale UITableViewCells based on the amount of content in them? In my cells I use 3 labels which represent a forum. The labels are named "alias", "date", and "comments". The third label comments, can be any number of rows. Therefore, my cells need to become dynamically depending on the amount of text(size) it is in the "comments" label. Below is my relevant code:
- (UITableViewCell *)tableView:(UITableView *)pTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ForumthreadCell";
UITableViewCell *cell = [pTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Feedback *item = [self.items objectAtIndex:indexPath.row];
UILabel *aliasLabel = (UILabel *)[cell viewWithTag:1];
UILabel *commentLabel = (UILabel *)[cell viewWithTag:2];
UILabel *dateLabel = (UILabel *)[cell viewWithTag:3];
[aliasLabel setText:item.alias];
[commentLabel setText:item.comment];
[dateLabel setText:[self.dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:(double)item.time]]];
commentLabel.numberOfLines = 0;
[commentLabel sizeToFit];
return cell;
}
In this method am I supposed to set the tableViewCell's height depending on commentLabel height.. The only problem is I am not sure how to do it?
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (????) {
return ????;
//return [indexPath row] + 50;
}
return ????;
}
I need help from someone that tries to take a look at my code and give examples how I can make this work. After all, its only 1 label.... I have already looked at several tutorials but not been able to make it work... Thanx for your time and help.
This is an old screen with some old code. This is more or less what the forum looks like now: http://tinypic.com/view.php?pic=16h7me9&s=6
What you need is a way to calculate the size of a text rendered with a specific font. Luckily, UIKit provides you with exactly this via the various sizeWithFont: methods in NSString UIKit Additions.

Resources