在 cellForItemAtIndexPath 中创建带有 NSTextAttachment 的 NSMutableAttributedString 是一个坏主意(性能或设计方面)吗?
Is NSMutableAttributedString with NSTextAttachment creation in cellForItemAtIndexPath a bad idea (performance or design wise)?
我正在我的集合视图的 cellForItemAtIndexPath
方法中创建 NSMutableAttributedString
。我正在使用 NSTextAttachment
在文本中嵌入图像。
这是个坏主意吗?目前滚动性能似乎不错,但我不确定是否有更好的方法?将所有 NSMutableAttributedString
缓存在 NSMutableDictionary
中对于第二次滚动会更好吗?
同样的问题也可以使用 cellForRowAtIndexPath
应用于 UITableview
。
代码:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CellView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[CellView reuseIdentifier] forIndexPath:indexPath];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"eye"];
attachment.bounds = CGRectMake(0, -2.5, 14,14);
NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
NSMutableAttributedString *myString= [[NSMutableAttributedString alloc] initWithString:@""];
[myString appendAttributedString:attachmentString];
[myString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@" 19K "]];
NSTextAttachment *attachment2 = [[NSTextAttachment alloc] init];
attachment2.image = [UIImage imageNamed:@"heart"];
attachment2.bounds = CGRectMake(0, -2.5, 14,14);
NSAttributedString *attachmentString2 = [NSAttributedString attributedStringWithAttachment:attachment2];
[myString appendAttributedString:attachmentString2];
[myString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@" 13K "]];
[myString enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[myString length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[myString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-Medium" size:12] range:range];
[myString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithWhite:1 alpha:1] range:range];
}];
NSMutableAttributedString *titletext= [[NSMutableAttributedString alloc] initWithString:[self checkIfBig:indexPath]?[NSString stringWithFormat:@"\nThe Underground Railway"]:[NSString stringWithFormat:@"\nPink Oasis"]];
[titletext enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[titletext length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[titletext addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-Medium" size:24] range:range];
[titletext addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range];
}];
[myString appendAttributedString:titletext];
if ([self checkIfBig:indexPath]){
NSMutableAttributedString *subtitletext= [[NSMutableAttributedString alloc] initWithString:@"\nLorem Ipsum is simply dummy text of the printing and typesetting industry."];
[subtitletext enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[subtitletext length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[subtitletext addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-Medium" size:14] range:range];
[subtitletext addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range];
}];
[myString appendAttributedString:subtitletext];
};
if ([self checkIfBig:indexPath]){
NSMutableAttributedString *subtitletext= [[NSMutableAttributedString alloc] initWithString:@"\n\n#HORROR #BLOOD"];
[subtitletext enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[subtitletext length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[subtitletext addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-MediumItalic" size:14] range:range];
[subtitletext addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range];
}];
[myString appendAttributedString:subtitletext];
};
cell.titleLabel.attributedText=myString;
return cell;
}
作为一般规则,您的数据应该在加载 table 视图或集合视图之前组装一次。在您当前的代码中,当用户来回滚动时,您会一遍又一遍地重新创建相同的数据。效率很低。
您的所有数据都应该在一个数组中(如果您有多个部分,则应在数组数组中)。您的 cellForRow|ItemAtIndexPath
应该只是从数组中获取一个对象,并且该对象的属性应该用于填充单元格。
如果您有很多行或某些数据更昂贵,您可以通过按需创建某些数据元素并缓存它们来改进上述内容,这样您仍然只创建一次。
正确完成后,您问题中的 cellForItemAtIndexPath
应该少于 5 行代码。
我正在我的集合视图的 cellForItemAtIndexPath
方法中创建 NSMutableAttributedString
。我正在使用 NSTextAttachment
在文本中嵌入图像。
这是个坏主意吗?目前滚动性能似乎不错,但我不确定是否有更好的方法?将所有 NSMutableAttributedString
缓存在 NSMutableDictionary
中对于第二次滚动会更好吗?
同样的问题也可以使用 cellForRowAtIndexPath
应用于 UITableview
。
代码:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CellView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[CellView reuseIdentifier] forIndexPath:indexPath];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = [UIImage imageNamed:@"eye"];
attachment.bounds = CGRectMake(0, -2.5, 14,14);
NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];
NSMutableAttributedString *myString= [[NSMutableAttributedString alloc] initWithString:@""];
[myString appendAttributedString:attachmentString];
[myString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@" 19K "]];
NSTextAttachment *attachment2 = [[NSTextAttachment alloc] init];
attachment2.image = [UIImage imageNamed:@"heart"];
attachment2.bounds = CGRectMake(0, -2.5, 14,14);
NSAttributedString *attachmentString2 = [NSAttributedString attributedStringWithAttachment:attachment2];
[myString appendAttributedString:attachmentString2];
[myString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@" 13K "]];
[myString enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[myString length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[myString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-Medium" size:12] range:range];
[myString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithWhite:1 alpha:1] range:range];
}];
NSMutableAttributedString *titletext= [[NSMutableAttributedString alloc] initWithString:[self checkIfBig:indexPath]?[NSString stringWithFormat:@"\nThe Underground Railway"]:[NSString stringWithFormat:@"\nPink Oasis"]];
[titletext enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[titletext length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[titletext addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-Medium" size:24] range:range];
[titletext addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range];
}];
[myString appendAttributedString:titletext];
if ([self checkIfBig:indexPath]){
NSMutableAttributedString *subtitletext= [[NSMutableAttributedString alloc] initWithString:@"\nLorem Ipsum is simply dummy text of the printing and typesetting industry."];
[subtitletext enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[subtitletext length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[subtitletext addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-Medium" size:14] range:range];
[subtitletext addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range];
}];
[myString appendAttributedString:subtitletext];
};
if ([self checkIfBig:indexPath]){
NSMutableAttributedString *subtitletext= [[NSMutableAttributedString alloc] initWithString:@"\n\n#HORROR #BLOOD"];
[subtitletext enumerateAttribute:NSFontAttributeName inRange:(NSRange){0,[subtitletext length]} options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
[subtitletext addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"AvenirNext-MediumItalic" size:14] range:range];
[subtitletext addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range];
}];
[myString appendAttributedString:subtitletext];
};
cell.titleLabel.attributedText=myString;
return cell;
}
作为一般规则,您的数据应该在加载 table 视图或集合视图之前组装一次。在您当前的代码中,当用户来回滚动时,您会一遍又一遍地重新创建相同的数据。效率很低。
您的所有数据都应该在一个数组中(如果您有多个部分,则应在数组数组中)。您的 cellForRow|ItemAtIndexPath
应该只是从数组中获取一个对象,并且该对象的属性应该用于填充单元格。
如果您有很多行或某些数据更昂贵,您可以通过按需创建某些数据元素并缓存它们来改进上述内容,这样您仍然只创建一次。
正确完成后,您问题中的 cellForItemAtIndexPath
应该少于 5 行代码。