2014-05-21 2 views
0

Я пытаюсь добавить UIView, который должен зачеркнуть текст (не беспокойтесь о горизонтальном смещении).Добавить subview в UITableViewCell по выбору

Однако при выборе строки строка добавляется несколькими строками ниже. Зачем?

Strange selection behaviour

Вот мой код:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSLog(@"%@", indexPath); 

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    UILabel *label = cell.textLabel; 

    CGSize textSize = [[label text] sizeWithAttributes:@{NSFontAttributeName:[label font]}]; 
    CGFloat strikeWidth = textSize.width; 

    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.height/2, 200, strikeWidth, 2)]; 
    lineView.backgroundColor = [UIColor redColor]; 

    lineView.tag = 100; 

    [cell.contentView addSubview:lineView]; 
} 

ответ

2

Вместо того, чтобы использовать UIView и добавить подвид в ячейку, вы должны использовать NSAttributedString для текста ячейки и NSStrikethroughStyleAttributeName ударить по с NSStrikethroughColorAttributeName для зачеркнутого цвета.

+0

Это только устанавливает атрибут текста, когда ячейка выбрана (когда вы держите палец на ячейке).Как только вы удаляете палец, удаляется прочерк. Мне нужно переключиться с помощью 'cell.textLabel.text' на' cell.textLabel.attributedText'? –

+0

Да, вы должны установить свой атрибут атрибута UILabel (предположительно в 'tableView: cellForRowAtIndexPath:', где создается ячейка). – KerrM

+0

Я нашел проблему. Я не обновляю Core Data, а '[tableView reloadData]' запускает 'cellForRowAtIndexPath', который запускает' [self configureCell] ', где я устанавливаю' cell.textLabel.text' :) –

0

Ваша проблема здесь:

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.height/2, 200, strikeWidth, 2)]; 

В этом случае, «я» является tableViewController, а не ярлык или клетка. Что вы делаете, устанавливая х происхождение зрения как половина высоты экрана, Y координаты вниз на 200 пунктов, с шириной strikeWidth и высотой 2.

, так как линия просмотр, который вы добавляете, будет подчиненным элементом ячейки, вы всегда хотите сделать кадр относительно его супервизора, который в этом случае является самой ячейкой. Скорее всего, вы хотите использовать что-то вроде похоже на ниже:

CGRectMake(CGRectGetMinX(cell.textLabel.frame), CGRectGetHeight(cell.contentView.frame)/2, strikeWidth, 2) 

Вы, вероятно, хотите изменить значения, чтобы сделать его линию, но вы получите идею ...

EDIT: добавлен Лучше кадр и вот еще код, который делает это красиво:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    UILabel *label = cell.textLabel; 

    CGSize textSize = [[label text] sizeWithAttributes:@{NSFontAttributeName:[label font]}]; 
    CGFloat strikeWidth = textSize.width; 

    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(label.frame), CGRectGetHeight(cell.contentView.frame)/2, strikeWidth, 2)]; 
    lineView.backgroundColor = [UIColor redColor]; 
    [cell.contentView addSubview:lineView]; 

    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 
} 
+1

Я думаю, что вы правы, но, вероятно, неправильно, что я - tableView. – danh

+0

Нет, сам IS tableView. – Mike

+0

Действительно? В каком классе вы предположите, что этот код делегата tableview появляется? – danh

0

Я думаю, что ваша линия появляется за пределами вашей клетки, потому что вы установили у происхождения 200 в кадре, который, кажется, довольно высок.

Кроме того, если вы хотите играть с зачеркиванием в UITableviewCell, вам лучше не делать этого таким образом, потому что при множественном выборе этот «strikethroughView» будет добавлен несколько раз и никогда не будет удален. Также в таблице reloadData или прокрутке ящики повторно используются, и вы не хотите, чтобы эти strikethroughViews отображались случайным образом.

Вот два способа сделать это правильно:

  • Используйте рамки NSAttributedString. В принципе, если вы можете делать всевозможные вещи в строке, например, задавать цвет, цвет фона, стиль абзаца, а также strikeThrough. Вот что я хотел бы написать в методе делегата didSelect:

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    NSString *string = cell.textLabel.text; 
    
    NSDictionary *attributes = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleThick)}; 
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes:attributes]; 
    cell.textLabel.attributedText = attributedString; 
    } 
    
  • Другим решением было бы добавить категорию на UICollectionViewCell и реализовать метод «setStrikeTrough» в нем.

Надеюсь, это поможет.

+0

Хорошее решение, единственное, что я бы изменил, вместо подкласса UICollectionViewCell, я бы создал категорию в UICollectionViewCell. – KerrM

+0

Вы правы, гораздо проще, поскольку это всего лишь метод. Я сделаю редактирование. – Kujey

Смежные вопросы