uitableviewcell textlabel too long and push detailtextlabel out of view
When i'm using UITableViewCellStyleValue1, i got a long string of textLabel, and somehow the detailTextLabel got push out from the view.
When i shorted my textLabel text, then i can see the detailTextLabel's text.
Is there anyway to limit the width of textLabel in the above style so that it will truncate the textLabel with it's too long?
My code is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cel开发者_StackOverflow中文版l";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;
//---get the letter in each section; e.g., A, B, C, etc.---
NSString *alphabet = [self.currencyNameIndex objectAtIndex:[indexPath section]];
//---get all states beginning with the letter---
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", alphabet];
self.currencyList = [self.keyCurrencyName filteredArrayUsingPredicate:predicate];
if ([self.currencyList count] > 0)
{
NSString *currencyName = [self.keyCurrencyName objectAtIndex:indexPath.row];
cell.textLabel.text = currencyName;
NSString *currencyCode = [self.valueCurrencyCode objectAtIndex:indexPath.row];
cell.detailTextLabel.text = currencyCode;
}
return cell;
}
so my currency name will be a long one on some entry.
Simplest for me was to subclass UITableViewCell and override the layoutSubviews.
Couldn't find a reliable way to calculate the positions from just the label frames so just hardcoded the accessory width for in this case a UITableViewCellStyleValue1 cell with a UITableViewCellAccessoryDisclosureIndicator accessory type.
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat detailTextLabelWidth = [self.detailTextLabel.text sizeWithFont:self.detailTextLabel.font].width;
CGRect detailTextLabelFrame = self.detailTextLabel.frame;
if (detailTextLabelFrame.size.width <= detailTextLabelWidth && detailTextLabelWidth > 0) {
detailTextLabelFrame.size.width = detailTextLabelWidth;
CGFloat accessoryWidth = (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) ? 28.0f : 35.0f;
detailTextLabelFrame.origin.x = self.frame.size.width - accessoryWidth - detailTextLabelWidth;
self.detailTextLabel.frame = detailTextLabelFrame;
CGRect textLabelFrame = self.textLabel.frame;
textLabelFrame.size.width = detailTextLabelFrame.origin.x - textLabelFrame.origin.x;
self.textLabel.frame = textLabelFrame;
}
}
@Jhaliya @lucas
cell.textLabel.numberOfLines = 3; // set the numberOfLines
cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;
see here: Custom UITableViewCell. Failed to apply UILineBreakModeTailTruncation
I ran into a similar problem when trying to use "Right Detail" in UITableView; the right detail's built in title label was clobbering my subtitle label.
Eventually I gave up on the "Right Detail" in favor of my own custom one (using swift and autolayout):
I created my own simple class that inherited from the UITableViewCell:
class TransactionCell: UITableViewCell { }
I set my prototype cell use that custom class by setting the "Style" field to "Custom" on the "Table View Cell" Menu and by adding "TransactionCell" to the "Class" field of the "Custom Class" menu. These menus are available when you select the prototype cell in the storyboard.
I added two labels to my prototype cell and connected them to my custom class by right click dragging from my labels to my class (Oddly, I had to clean my build before it would let me do this):
class TransactionCell: UITableViewCell{ @IBOutlet weak var detailsLabel: UILabel! @IBOutlet weak var amountLabel: UILabel! }
I added new constraints to my labels, taking advantage of swift's autolayout features (You will need to set these to match your own requirements; see a tutorial on autolayout if you are stuck)
- ...and set the "Lines" and "Line Breaks" fields in the respective "Label" menus so that the spacing between labels would be even and so that my details label could flex to multiple lines.
It worked for me, allowing me to have the flexibility of different amounts of multiple lines in a UITableView in swift per cell, while formatting the word wrapping so that it looked nice and even, like I would have expected the "Right Detail" to do automatically.
I had the same problem and had to create a UITableViewCell subclass. It's easier to do that than I thought:
Basically, just make a new file, that is a subclass of UITableViewCell
Add the labels and synthesize them:
// in the .h file
@property (nonatomic, weak) IBOutlet UILabel *textLabel;
@property (nonatomic, weak) IBOutlet UILabel *detailTextLabel;
// in the .m file
@synthesize textLabel, detailTextLabel;
In the StoryBoard, set your class as the cell's class, make the Style "Custom" and add two labels in the cell to look exactly as you want (I made them look the same as the default: http://cl.ly/J7z3)
The most important part is to make sure you connect the labels to the cell
You need to control-click from the Cell to the label in the Document outline. Here's a picture of what it looks like: http://cl.ly/J7BP
What helped me to understand how to create custom cell, dynamic cells, and static cells is this youtube video: http://www.youtube.com/watch?v=fnzkcV_XUw8
Once you do that, you should be all set. Good luck!
Swift version supporting the latest iOS (12):
override func layoutSubviews() {
super.layoutSubviews()
guard let detailWidth = detailTextLabel?.intrinsicContentSize.width, var detailFrame = detailTextLabel?.frame else {
return
}
let padding = layoutMargins.right
if (detailFrame.size.width <= detailWidth) && (detailWidth > 0) {
detailFrame.size.width = detailWidth
detailFrame.origin.x = frame.size.width - detailWidth - padding
detailTextLabel?.frame = detailFrame
var textLabelFrame = textLabel!.frame
textLabelFrame.size.width = detailFrame.origin.x - textLabelFrame.origin.x - padding
textLabel?.frame = textLabelFrame
}
}
Adjust the frame of the view: textLabel
CGRect aFrame = cell.textLabel.frame;
aFrame.size.width = 100; // for example
cell.textLabel.frame = aFrame;
Updated Gosoftworks Development`s answer.
Swift 3
class BaseTableViewCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
guard let tl = textLabel, let dl = detailTextLabel else { return }
if (tl.frame.maxX > dl.frame.minX) {
tl.frame.size.width = dl.frame.minX - tl.frame.minX - 5
}
}
}
Create a custom UITableViewCell with a UILabel in it that you can control however you want, or truncate the text that you assign to the base-class textLabel to fit the space that you have.
It's not perfect, but I have used the text-truncation technique in places where a custom cell is overkill (ex. when the only issue was fitting the text in) using an NSString category with a method similar to the following:
- (NSString *)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font
{
NSString *result = [NSString stringWithString:self];
while ([result sizeWithFont:font].width > width)
{
result = [result stringByReplacingOccurrencesOfString:@"..." withString:[NSString string]];
result = [[result substringToIndex:([result length] - 1)] stringByAppendingString:@"..."];
}
return result;
}
Probably not 'optimized' but it works for simple scenarios.
1st: set line break mode
textLabel.lineBreakMode = NSLineBreakByTruncatingTail;
2nd: set texLabel frame width you want (e.g. 200)
CGRect textFrame = self.textLabel.frame;
CGRect newTextFrame = CGRectMake(textFrame.origin.x, textFrame.origin.y, 200, textFrame.size.height);
self.textLabel.frame = newTextFrame;
It works!! But i just changed Christopher King`s code:
- (NSString *)stringByTruncatingToWidth:(CGFloat)width withFont:(UIFont *)font :(NSString*) result
{
while ([result sizeWithFont:font].width > width)
{
result = [result stringByReplacingOccurrencesOfString:@"..." withString:[NSString string]];
result = [[result substringToIndex:([result length] - 1)] stringByAppendingString:@"..."];
}
return result;
}
and usage:
NSString* text = @"bla bla bla some long text bla bla";
text = [self stringByTruncatingToWidth:cell.frame.size.width-70.0 withFont:[UIFont systemFontOfSize:17] :text];
cell.textLabel.text = text;
I've struggled with this a bunch and found a pretty simple answer. My textLabel
was on the left and would push out the detailText
on the right to the point you couldn't see it at all sometimes.
My solution, change the Table View Cell
style
to Subtitle
from Left Detail
or Right Detail
. This solution works if you don't mind your detailText
being below instead of on the right or left.
If you are having issues with the height of the row, you can adjust that using the code below in viewDidLoad
.
self.tableView.estimatedRowHeight = 500 // set this as high as you might need, although I haven't tested alternatives
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.reloadData()
Use the UILabel lineBreakMode
property to restrict your text within the width of your UILabel
@property(nonatomic) UILineBreakMode lineBreakMode
Use it as below.
myLabel.lineBreakMode = UILineBreakModeTailTruncation;
Here is the list of values which could be used with lineBreakMode
.
http://developer.apple.com/library/ios/#documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference.html#//apple_ref/doc/c_ref/UILineBreakMode
EDITED:
Set the width of your UILabel
as per your requirment
eg.
myLabel.frame.size.width = 320;
精彩评论