2016-04-22 4 views
0

У меня есть customCell и мне нужно добавить несколько UILabel, как «метка» для каждой ячейки, Моего кода выглядит так:предотвратить UILabel повтора добавлен в пользовательских UITableViewCell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *ID = @"topicCell"; 
    MSPTopicCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 
    NSArray *labelArray = [TopicLabelArr objectAt:index.row]; 
    for (int i = 0; i < [labelArray count]; i++) { 
     UILabel *tmpLabel = [UILabel alloc]initwithFrame .....]; 
     tmpLabel.text = [labelArray objectAt:i]; 
     [cell.view addSubview:tmpLabel]; 
    } 
    return cell; 
} 

Я использую XIb для создания пользовательская ячейка. Мне нужно, чтобы for-loop выполнялся только один раз в каждой ячейке. Однако в tableView много строк, и метки будут создаваться повторяется каждый раз, когда я просматриваю вверх и вниз. Как его улучшить? Есть идеи? Благодарю.

+0

установить флаг bool перед тем, как добавить ярлык. –

+0

Обновите свой вопрос с помощью метода 'cellForAtIndexPath'. – rmaddy

+0

Код был обновлен. Спасибо за ваш ответ. –

ответ

4

Когда вы используете dequeueReusableCellWithIdentifier, вы не создаете новый MSPTopicCell вы (как говорит название метода) повторно используйте ячейку.

Что это значит? Очевидно, что вам нужно как минимум столько же ячеек, сколько вы показываете одновременно, но как только вы начнете прокрутку, ячейки, которые исчезают из вашего scrollview, повторно используются.

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

Есть много способов, чтобы это исправить, вот несколько примеров:

  • Вы можете удалить подвиды добавлены перед добавлением новых. Добавьте следующую строку перед циклом, используя следующий код:

    view.subviews.forEach({ $0.removeFromSuperview() } 
    
  • Используйте пользовательские метки для этикеток, так что вы можете увидеть его они уже существуют или нет:

    for (int i = 0; i < [labelArray count]; i++) { 
        UILabel *tmpLabel = (UILabel *)[self viewWithTag:100+i]; 
        if (tmpLabel == nil) 
        { 
         tmpLabel = [UILabel alloc]initwithFrame .....]; 
         tmpLabel.tag = 100 + i; 
         [cell.view addSubview:tmpLabel]; 
        } 
        tmpLabel.text = [labelArray objectAt:i]; 
    } 
    
  • Лучшего решения , на мой взгляд, поскольку вы уже используете подкласс UITableViewCell: просто прямо добавьте некоторые свойства UILabel на свой класс MSPTopicCell, поэтому вам не нужно его создавать в cellForRowAtIndexPath. Но, возможно, этот случай не адаптирован для вас, поскольку число меток зависит от labelArray, которые являются зависимыми от положения ячейки.

+0

Не рекомендуется использовать теги, pleeeeease! Это буквально самый худший способ приблизиться к этому. Удалите вторую (и первую) часть из вашего ответа, и вы получите +1. Я не могу дать +1 atm, хотя, как вы рекомендуете использовать теги. – Fogmeister

+0

Извините за показ, я просто хотел показать несколько подходов.Я знаю, что они плохие и склонны к ошибкам, это была просто культура. Как вы думаете, я должен держать их в ответе за культуру или удалить эту часть, чтобы эта часть рамки iOS оставалась скрытой? –

+0

все зависит от вас. Я думаю, этого достаточно, чтобы показать подкласс. Это лучший подход к этому. Проблема с тегами заключается в том, что люди начинают полагаться на uiview для хранения случайных бит данных. Я всегда стараюсь отговорить его :-) – Fogmeister

0

Вы можете создать UIView, который будет включать в себя все ваши UILabel. Однако, когда вы используете , повторите использование ячейки в начале, просто удалите этот вид из супервизора. Итак, masterview будет удален из вашей камеры.

т.е.

[[cell.contentView viewWithTag:101] removeFromSuperview] 
UIView *yourViewName = [[UIView alloc]init]; 
// set your view's frame based on cell. 
yourViewName.tag = 101; 
for (int i = 0; i < [labelArray count]; i++) { 
    UILabel tmpLabel = (UILabel)[self viewWithTag:100+i]; 
    if (tmpLabel == nil) 
    { 
     tmpLabel = [UILabel alloc]initwithFrame .....]; 
     tmpLabel.tag = 100 + i; 
     [yourViewName addSubview:tmpLabel]; 
    } 
    tmpLabel.text = [labelArray objectAt:i]; 
} 
[cell.contentView addSubView:yourViewName]; 

Этот процесс ускорит прокрутку производительности клетки, а также.

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