2015-02-03 2 views
0

У меня есть UICollectionViewController, который отображает блоки телефонных номеров (см. Изображение). Когда загружаются представления, все они кажутся точными, однако, когда я либо начинаю прокрутку, меняя вращение, либо выполняю функцию поиска, которая изменяет (изменяемый) массив, в котором хранятся данные, я вижу эти искаженные метки. Я действительно думал, что это может быть симулятор iOS, однако, глядя на него, это, похоже, проблема с позиционированием UICollectionViewCells.iOS, UICollectionViewCell malformed UILabel

enter image description here

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 
    static NSString *identifier = @"cell"; 
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; 

    cell.backgroundColor = [UIColor grayColor]; 
    cell.layer.cornerRadius = 5; 
    [cell setClipsToBounds: YES]; 

    CGRect cellBound = CGRectMake(25, 12.5, 150, 12.5); // x, y, w, h 
    UILabel *title = [[UILabel alloc] initWithFrame:cellBound]; 

    NSString *number = [[searchNumbers objectAtIndex:indexPath.row] valueForKey:@"number"]; 
    number = [number stringByReplacingOccurrencesOfString:@"+44" withString: @"0"]; 
    title.text = number; 

    [cell addSubview:title]; 
    return cell; 
} 

Следует отметить, что я использую UICollectionViewFlowLayout

ответ

1

Как упоминалось @Woodstock, это происходит из-за «чрезмерного добавления» объектов в вашу камеру.

Вместо того, чтобы его решение, которое еще добавляет UILabel к клетке в -collectionView:cellForRowAtIndexPath:, лучшее решение MVC это:

// A UICollectionViewCell subclass 
// Make sure to pick the correct "init" function for your use case 
- (instancetype)init... { 
    self = [super init...]; 
    if (self != nil) { 
     [self setupCell]; 
    } 
    return self; 
} 
- (void)setupCell { 
    self.backgroundColor = [UIColor grayColor]; 
    self.clipsToBounds  = YES; 
    self.layer.cornerRadius = 5; 
    CGRect cellBound  = CGRectMake(25, 12.5, 150, 12.5); // x, y, w, h 
    // Assumes you've set up a UILabel property 
    self.titleLabel   = [[UILabel alloc] initWithFrame:cellBound]; 
    [cell addSubview:self.titleLabel]; 
} 
- (void)configureWithNumber:(NSString *)number { 
    number     = [number stringByReplacingOccurrencesOfString:@"+44" withString: @"0"]; 
    self.titleLabel.text = number; 
} 

// In your UICollectionViewDataSource/Delegate implementation 
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *identifier = @"cell"; 
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; 
    NSString *number   = [[searchNumbers objectAtIndex:indexPath.row] valueForKey:@"number"]; 
    [cell configureWithNumber:number]; 
    return cell; 
} 

В принципе, вы хотите настроить и добавить взгляды только когда сначала устанавливая ячейку. После этого вы должны передать значение/объект данных и configure ячейка. Если у вас есть ячейки, которым нужны разные элементы управления (2 метки против 1 и т. Д.), Тогда создайте несколько подклассов. Таким образом, вы инкапсулируете свои классы для более чистого кода и лучшего повторного использования.

+0

вы совершенно правы :) Мой ответ просто объясняет, что не так, как это сделать правильно, поддержал! – Woodstock

+0

очень хороший способ достижения этого :) –

1

Я считаю, что это происходит потому, что вы добавляете все больше и больше UILabel подвидов в камеру (снова и снова, как cellForItemAtIndexPath является называется). Вам нужно добавить чек, а добавить только надпись подклассов, если ячейка еще не имеет одного. У выделенных ячеек уже есть надпись label, если они повторно используются, если эта метка уже существует, вам просто нужно установить ее текст из вашего источника данных.

псевдокод:

for subview in subviews { 
    if subview.isKindOfClass(UILabel) { 
     // assign the new text label. 
    } 
    else 
    { 
     // create and add the UILabel subView. 
    } 

} 

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