ИНФОРМАЦИЯ:
У меня есть Tableview, в котором есть ячейки с Imageview. В этом представлении изображений я извлекаю разные изображения из imgURL...
Что мне нужно:
Мне нужна динамическая высота ячейки в соответствии с высотой изображения, полученной из imgURL.
ПРИМЕЧАНИЕ. Я не использую автоматическую компоновку, но использую автоматическое изменение размера.
Что я сделал до сих пор:
Я использовал асинхронную загрузку изображений в ImageView. (от #import "UIImageView+WebCache.h")
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
HomePostCell *cell=[tableView dequeueReusableCellWithIdentifier:strIdentifier];
if (cell==nil) {
cell = [[HomePostCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:strIdentifier];
}
[cell.imgMain sd_setImageWithURL:[NSURL URLWithString:strImgURL] placeholderImage:[UIImage imageNamed:@"postPlaceholder"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (!error) {
}];
return cell;
}

Есть ли какое-нибудь решение для этого? или мы можем использовать автоматическую компоновку только для изменения размера ячейки?
Заранее спасибо..
Ответ 1 · рейтинг 4 · ozgur
В идеальном случае я обычно ожидаю, что API вернет все изображения одинакового размера или размера, который можно настроить с помощью параметров строки запроса, таких как: /get_image/?width=400&height=400 и т. д.
В любом случае, проблема здесь в том, что вы не можете обновить высоту ячейки после того, как она была создана и готова к отображению на экране (другими словами, после того, как она была возвращена из cellForRowAtIndexPath) если вы не перезагрузите эту ячейку или все табличное представление вручную. К счастью для нас, sd_setImageWithURL работает асинхронно, что означает, что у вас будет возможность вызвать tableView.reloadRowsAtIndexPath после того, как изображение будет получено и сохранено.
Перезагрузка приведет к вызову heightForRowAtIndexPath для перезагруженной ячейки, поэтому на этот раз мы получим правильную высоту.
(Поскольку ячейки табличного представления являются повторно используемыми объектами, они не хранят никакой информации о данных, которые они используют для настройки своего пользовательского интерфейса. Таким образом, вам нужно хранить изображения в контроллере представления, желательно внутри массива.)
@interface ViewController ()
@property (nonatomic, strong) NSMutableArray *fetchedImages;
@end
@implementation ViewController
...
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UIImage *image = [self.fetchedImages objectAtIndex:indexPath.row];
if (image) {
return image.size.height + 1.0; // 1.0 for the separator.
}
else {
return 50.0; // Default value..
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.fetchedImages.count;
}
С учетом всего сказанного вы можете сделать что-то вроде следующего в методе (tableView:cellForRowAtIndexPath:):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
UIImage *image = [self.fetchedImages objectAtIndex:indexPath.row];
if (image) {
// If there is image don't bother fetching the image.
cell.imageView.image = image;
}
else {
NSURL *imageURL = [self.imageURLs objectAtIndex:indexPath.row];
[cell.imageView sd_setImageWithURL:imageURL placeholderImage:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (image) {
[self.fetchedImages replaceObjectAtIndex:indexPath.row withObject:image];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
}];
return cell;
}
Вот результат, который у меня получился:
Вы можете загрузить тестовый проект и поэкспериментировать с ним, чтобы получить лучшее понимание того, что я сделал выше.
Ответ 2 · рейтинг 1 · Monika Patel
этот код работает с автоматическим изменением размера, может вам помочь.
#define Screen_Width [[UIScreen mainScreen] bounds].size.width
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
{
return imageHeight;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NativeStreamAdCell *cell=(NativeStreamAdCell *)[tableView dequeueReusableCellWithIdentifier:@"SimpleTable"];
if(cell==nil)
{
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:@"NativeStreamAdCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
}
[cell.postImg sd_setImageWithURL:[NSURL URLWithString:[dic_feed valueForKey:@"feed_image"]] placeholderImage:cell.postImg.image options:SDWebImageRefreshCached];
//Display image based on size
UIImage *img = cell.postImg.image;
int image_width = img.size.width;
int image_height = img.size.height;
image_width = Screen_Width;
image_height = (Screen_Width * img.size.height / img.size.width);
if(image_width > image_height) {
image_height = (Screen_Width * image_height / image_width);
}
cell.postImg.frame = CGRectMake(cell.postImg.frame.origin.x, cell.postImg.frame.origin.y,
image_width,image_height);
imageHeight = CGRectGetMaxY(cell.postImg.frame);
return cell;
}
Ответ 3 · Phu Nguyen
Далее следует пример Ozgur Vatansever, но он мерцает при быстрой прокрутке.
Даже это не помогло.
Я обнаружил, что [self.tableView reloadData] работает вместо
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
OR
[weakSelf.tableView beginUpdates];
[weakSelf.tableView endUpdates];