Currently I am using an outlet of the imageView height constraint in order to adjust the height of the imageView like so:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
cell.productImageView.file = (PFFile *)object[@"image"];
[cell.productImageView loadInBackground:^(UIImage * _Nullable image, NSError * _Nullable error) {
cell.imageHeightConstraint.constant = image.size.height / image.size.width * cell.cardView.frame.size.width;
[cell.productImageView setNeedsUpdateConstraints];
[UIView animateWithDuration:0.50f animations:^{
[cell.cardView layoutIfNeeded];
}];
}];
In viewDidLoad
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 350;
Is there a better way to change the height of the ImageView than to use a outlet to the height constraint?
I have to end up scrolling to have it update to the updated height constraint.
reload your tableView
in viewWillAppear
or viewDidAppear
something like this,
-(void)viewDidAppear:(BOOL)animated{
[self.tableView reloadData];
}
I doubt if your code is also resizing the cell based on image height. Inside the block where you update the imageView height constraint also put this code:
let indexPath = self.tableView.indexPathForCell(cell)
if indexPath != nil {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
Objective C :
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
if (indexPath != nil) {
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
You should only modify the UI on the main thread. This means that you should change your callback from this:
[cell.productImageView loadInBackground:^(UIImage * _Nullable image, NSError * _Nullable error) {
// code here
}];
to this, which uses Grand Central Dispatch to run on the main thread.
[cell.productImageView loadInBackground:^(UIImage * _Nullable image, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
// code here. Will be run after dispatch_async returns.
});
}];
Edit :
This will be slow because -tableView:cellForRowAtIndexPath:
, and therefore -tableView:cellForRowAtIndexPath:object:
are called whenever a cell scrolls into view. It is better to cache your images (both for performance and for your users' mobile data). A built-in way to do this is NSCache
. To do this, add a property to your class:
@property (strong, nonatomic) NSCache *cache;
Then, in your viewDidLoad
, create your cache:
self.cache = [[NSCache alloc] init];
When you load an image in -tableView:cellForRowAtIndexPath:object:
, do something like this:
void (^updateView)(UIImage *) = ^(UIImage * _Nullable image) {
cell.imageHeightConstraint.constant = image.size.height / image.size.width * cell.cardView.frame.size.width;
[cell.productImageView setNeedsUpdateConstraints];
[UIView animateWithDuration:0.50f animations:^{
[cell.cardView layoutIfNeeded];
}];
}];
UIImage *cached = [self.cache objectForKey:cell.productImageView.file];
if (cached) {
cell.productImageView.image = cached;
updateView(cached);
} else {
[cell.productImageView loadInBackground:^(UIImage * _Nullable image, NSError * _Nullable error) {
if (!error) {
[self.cache setObject:image forKey:cell.productImageView.file];
}
updateView(image);
}];
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.