Слишком длинная текстовая метка в uitableviewcell и выталкивает текстовую метку из поля зрения
Когда я использую UITableViewCellStyleValue1, я получил длинную строку textLabel, и как-то detailTextLabel вытолкнуло из вида.
Когда я замкнул текст textLabel, я смог увидеть текст detailTextLabel.
Есть ли способ ограничить ширину textLabel в вышеприведенном стиле, чтобы он урезал textLabel слишком длинным?
Мой код:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
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;
}
поэтому название моей валюты будет длинным в какой-то записи.
11 ответов
Используйте UILabel lineBreakMode
свойство ограничить ваш текст в ширину вашего UILabel
@property(nonatomic) UILineBreakMode lineBreakMode
Используйте это как ниже.
myLabel.lineBreakMode = UILineBreakModeTailTruncation;
Вот список значений, которые можно использовать с lineBreakMode
,
Редакция:
Установите ширину вашего UILabel
согласно вашему требованию
например.
myLabel.frame.size.width = 320;
Самым простым для меня было создать подкласс UITableViewCell и переопределить layoutSubviews.
Не удалось найти надежный способ вычисления позиций только из рамок меток, поэтому просто жестко закодировали ширину аксессуара для в этом случае ячейки UITableViewCellStyleValue1 с типом аксессуара UITableViewCellAccessoryDisclosureIndicator.
- (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;
смотрите здесь: Custom UITableViewCell. Не удалось применить UILineBreakModeTailTruncation
Я столкнулся с подобной проблемой при попытке использовать "Right Detail" в UITableView; встроенная метка заголовка нужной детали засоряла мою метку субтитров.
В конце концов я отказался от "Правой детализации" в пользу своей собственной (используя swift и autolayout):
Я создал свой собственный простой класс, который унаследован от UITableViewCell:
class TransactionCell: UITableViewCell { }
Я установил в своей ячейке-прототипе использование этого пользовательского класса, установив для поля "Стиль" значение "Пользовательский" в меню "Ячейка табличного представления" и добавив "TransactionCell" в поле "Класс" в меню "Пользовательский класс". Эти меню доступны, когда вы выбираете ячейку прототипа в раскадровке.
Я добавил две метки в свою ячейку-прототип и соединил их с моим пользовательским классом, перетаскивая правую кнопку мыши из моих меток в мой класс (как ни странно, мне пришлось очистить сборку, прежде чем она позволила бы мне это сделать):
class TransactionCell: UITableViewCell{ @IBOutlet weak var detailsLabel: UILabel! @IBOutlet weak var amountLabel: UILabel! }
Я добавил новые ограничения на свои ярлыки, используя преимущества функции автоматической разметки swift (вам нужно будет установить их в соответствии со своими требованиями; см. Учебник по автоматической разметке, если вы застряли)
- ... и установите поля "Линии" и "Разрывы строк" в соответствующих меню "Метка", чтобы расстояние между метками было одинаковым и чтобы моя метка сведений могла сгибаться до нескольких строк.
Это сработало для меня, позволяя мне иметь гибкость в различном количестве нескольких строк в UITableView в быстрой смене на ячейку, при этом форматируя перенос слов, чтобы он выглядел красиво и ровно, как я и ожидал, что "Правая деталь" сделает автоматически.
У меня была та же проблема, и я должен был создать подкласс UITableViewCell. Это проще сделать, чем я думал
По сути, просто создайте новый файл, который является подклассом UITableViewCell
Добавьте метки и синтезируйте их:
// in the .h file
@property (nonatomic, weak) IBOutlet UILabel *textLabel;
@property (nonatomic, weak) IBOutlet UILabel *detailTextLabel;
// in the .m file
@synthesize textLabel, detailTextLabel;
В StoryBoard установите свой класс в качестве класса ячейки, сделайте стиль "Пользовательским" и добавьте две метки в ячейку, чтобы они выглядели именно так, как вы хотите (я сделал так, чтобы они выглядели так же, как по умолчанию: http://cl.ly/J7z3)
Самая важная часть - убедиться, что вы подключили метки к ячейке.
Необходимо щелкнуть элемент управления в ячейке с помощью ярлыка на схеме документа. Вот изображение того, на что это похоже: http://cl.ly/J7BP
Что помогло мне понять, как создавать пользовательские ячейки, динамические ячейки и статические ячейки, так это видео на YouTube: http://www.youtube.com/watch?v=fnzkcV_XUw8
Как только вы это сделаете, у вас все будет готово. Удачи!
Версия Swift, поддерживающая последнюю версию 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
}
}
Обновленный ответ Гософтворк Девелопмент.
Свифт 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
}
}
}
Настройте рамку вида: textLabel
CGRect aFrame = cell.textLabel.frame;
aFrame.size.width = 100; // for example
cell.textLabel.frame = aFrame;
Создайте пользовательский UITableViewCell с UILabel, которым вы можете управлять, как хотите, или обрежьте текст, который вы назначаете textLabel базового класса, чтобы он соответствовал имеющемуся пространству.
Это не идеально, но я использовал технику усечения текста в тех местах, где пользовательская ячейка перебита (например, когда единственная проблема заключалась в подгонке текста), используя категорию NSString с методом, подобным следующему:
- (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;
}
Вероятно, не "оптимизирован", но он работает для простых сценариев.
1-й: установить режим разрыва строки
textLabel.lineBreakMode = NSLineBreakByTruncatingTail;
2-й: установите желаемую ширину рамки texLabel (например, 200)
CGRect textFrame = self.textLabel.frame;
CGRect newTextFrame = CGRectMake(textFrame.origin.x, textFrame.origin.y, 200, textFrame.size.height);
self.textLabel.frame = newTextFrame;
Я боролся с этой связкой и нашел довольно простой ответ. мой textLabel
был слева и будет выталкивать detailText
справа до точки, которую ты иногда вообще не видел.
Мое решение, измените Table View Cell
style
в Subtitle
от Left Detail
или же Right Detail
, Это решение работает, если вы не против detailText
быть внизу, а не справа или слева.
Если у вас есть проблемы с высотой строки, вы можете отрегулировать это, используя код ниже в 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()
Оно работает!! Но я только что изменил код Кристофера Кинга:
- (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;
}
и использование:
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;