sizeForItemAtIndexPath getting called for all indexes before load - I am pretty sure I am either running into...
I am able to reproduce this on a very simple standalone app.
I have a collectionView which I want to make circular/loop so the elements repeat again and again (aka when user is at the last element in array, it shows the first element again after. And if they are at the first and scroll left, it shows the last element again). So it's a never ending collectionView.
So for a simple example, let's use days of week:
....Sunday, Monday, Tuesday, Wednesday..Saturday, Sunday, Monday....
In order to achieve this, I return a big number (10000) in the numberOfItemsInSection
and use indexPath.item%7
in the cellForItemAtIndexPath
method to adjust and get the correct element. Using %7
as there are 7 days.
My cells are very simple - just a UILabel in it.
This all works perfectly.
The issue comes with the sizeForItemAtIndexPath
. I want the cells to fit the label. As there would only be 7 actual size variations, so I pre-cache the sizes of the 7 days in a dictionary and return the correct size in sizeForItemAtIndexPath
method.
The problem is that (either due to a bug or intentional bad design by Apple of collectionview), the sizeForItemAtIndexPath
gets calls for every indexPath before the collectionview appears. So if I want to have the circular collectionView logic and need to return the big number (10000), it's is calling sizeForItemAtIndexPath
for all 10000 indexes. So there is a couple seconds lag until the collectionView appears. If I comment out the sizeForItemAtIndexPath
, then it works instantly. So that's definitely the issue. I put a NSLog
in the sizeForItemAtIndexPath
and it logs all the 22222 calls before load.
I have even defined the setEstimatedItemSize
, it still calls sizeForItemAtIndexPath
for all indexes.
I can reduce the lag by returning a smaller number 1000 but still, this is a bad design or bug for sure.
TableView doesn't have this bug - you can define a million rows and it only calls the heightForRow when it actually needs it. So I am not sure why collectionView needs to call it for all cells before showing, especially if setEstimatedItemSize
is already defined too.
Another side-effect of this bug is that the collectionView throws an error if I return a bigger value (50000 makes it break, 22222 is okay). It prints the error for too big values:
This NSLayoutConstraint is being configured with a constant that exceeds internal limits. A smaller value will be substituted, but this problem should be fixed. Break on BOOL _NSLayoutConstraintNumberExceedsLimit(void) to debug. This will be logged only once. This may break in the future.
TableView can easily handle huge values because it doesn't have this bug.
I have also tried disabling prefetching
but that had no effect.
What do you all think?
Relevant code:
#define kInfiniteCount 22222
#define kDayNameMargin 30
@interface ViewController (){
NSMutableDictionary *dictOfSizes;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
self.myCalendar = [NSCalendar currentCalendar];
[self.myCalendar setLocale:locale];
dictOfSizes = [NSMutableDictionary new];
for (int i=0; i<7; i++) {
WeekdayCollectionViewCell *sizingCell = [[NSBundle mainBundle] loadNibNamed:@"WeekdayCell" owner:self options:nil][0];
sizingCell.myLabel.text=[self.myCalendar weekdaySymbols][i];
[sizingCell layoutIfNeeded];
[dictOfSizes setObject:[NSValue valueWithCGSize:[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]] forKey:sizingCell.myLabel.text];
}
self.myCollectionView.decelerationRate = UIScrollViewDecelerationRateFast;
[self.myCollectionView registerNib:[UINib nibWithNibName:@"WeekdayCell" bundle:nil] forCellWithReuseIdentifier:@"daycell"];
[(UICollectionViewFlowLayout*)self.myCollectionView.collectionViewLayout setEstimatedItemSize:CGSizeMake(200, self.myCollectionView.frame.size.height)];
[self.myCollectionView reloadData];
NSInteger middleGoTo = kInfiniteCount/2;
while (![[self.myCalendar weekdaySymbols][middleGoTo%7] isEqualToString:@"Monday"]) {
middleGoTo--;
}
[self.myCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:middleGoTo inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return kInfiniteCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
WeekdayCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"daycell" forIndexPath:indexPath];
cell.myLabel.text=[self.myCalendar weekdaySymbols][indexPath.item%7];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"sizeForItemAtIndexPath: %ld",indexPath.item);
return [(NSValue*)[dictOfSizes objectForKey:[self.myCalendar weekdaySymbols][indexPath.item%7]] CGSizeValue];
}
EDIT:
Few people mentioned using scrollview instead of collectionview for this.
Pretty much everywhere I researched for the circular scrollview, they recommended using a collectionview for this purpose as it's much easier. My real requirement is a bit more complex which requires me to use collectionview too.
Scrollview requires you to use the scrollViewDidScroll method and change the content offset each time. Plus it loads all views in memory at once as it doesn't have the advantage of reusing existing cells like collectionview does. So that's another memory hit.
The 7 weekdays is a simple example I used. If someone wants to show a lot of data (100), that would be a pretty bad implementation in scrollview and collectionview will present this bug.
ios objective-c swift uicollectionview uicollectionviewlayout
add a comment |
I am able to reproduce this on a very simple standalone app.
I have a collectionView which I want to make circular/loop so the elements repeat again and again (aka when user is at the last element in array, it shows the first element again after. And if they are at the first and scroll left, it shows the last element again). So it's a never ending collectionView.
So for a simple example, let's use days of week:
....Sunday, Monday, Tuesday, Wednesday..Saturday, Sunday, Monday....
In order to achieve this, I return a big number (10000) in the numberOfItemsInSection
and use indexPath.item%7
in the cellForItemAtIndexPath
method to adjust and get the correct element. Using %7
as there are 7 days.
My cells are very simple - just a UILabel in it.
This all works perfectly.
The issue comes with the sizeForItemAtIndexPath
. I want the cells to fit the label. As there would only be 7 actual size variations, so I pre-cache the sizes of the 7 days in a dictionary and return the correct size in sizeForItemAtIndexPath
method.
The problem is that (either due to a bug or intentional bad design by Apple of collectionview), the sizeForItemAtIndexPath
gets calls for every indexPath before the collectionview appears. So if I want to have the circular collectionView logic and need to return the big number (10000), it's is calling sizeForItemAtIndexPath
for all 10000 indexes. So there is a couple seconds lag until the collectionView appears. If I comment out the sizeForItemAtIndexPath
, then it works instantly. So that's definitely the issue. I put a NSLog
in the sizeForItemAtIndexPath
and it logs all the 22222 calls before load.
I have even defined the setEstimatedItemSize
, it still calls sizeForItemAtIndexPath
for all indexes.
I can reduce the lag by returning a smaller number 1000 but still, this is a bad design or bug for sure.
TableView doesn't have this bug - you can define a million rows and it only calls the heightForRow when it actually needs it. So I am not sure why collectionView needs to call it for all cells before showing, especially if setEstimatedItemSize
is already defined too.
Another side-effect of this bug is that the collectionView throws an error if I return a bigger value (50000 makes it break, 22222 is okay). It prints the error for too big values:
This NSLayoutConstraint is being configured with a constant that exceeds internal limits. A smaller value will be substituted, but this problem should be fixed. Break on BOOL _NSLayoutConstraintNumberExceedsLimit(void) to debug. This will be logged only once. This may break in the future.
TableView can easily handle huge values because it doesn't have this bug.
I have also tried disabling prefetching
but that had no effect.
What do you all think?
Relevant code:
#define kInfiniteCount 22222
#define kDayNameMargin 30
@interface ViewController (){
NSMutableDictionary *dictOfSizes;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
self.myCalendar = [NSCalendar currentCalendar];
[self.myCalendar setLocale:locale];
dictOfSizes = [NSMutableDictionary new];
for (int i=0; i<7; i++) {
WeekdayCollectionViewCell *sizingCell = [[NSBundle mainBundle] loadNibNamed:@"WeekdayCell" owner:self options:nil][0];
sizingCell.myLabel.text=[self.myCalendar weekdaySymbols][i];
[sizingCell layoutIfNeeded];
[dictOfSizes setObject:[NSValue valueWithCGSize:[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]] forKey:sizingCell.myLabel.text];
}
self.myCollectionView.decelerationRate = UIScrollViewDecelerationRateFast;
[self.myCollectionView registerNib:[UINib nibWithNibName:@"WeekdayCell" bundle:nil] forCellWithReuseIdentifier:@"daycell"];
[(UICollectionViewFlowLayout*)self.myCollectionView.collectionViewLayout setEstimatedItemSize:CGSizeMake(200, self.myCollectionView.frame.size.height)];
[self.myCollectionView reloadData];
NSInteger middleGoTo = kInfiniteCount/2;
while (![[self.myCalendar weekdaySymbols][middleGoTo%7] isEqualToString:@"Monday"]) {
middleGoTo--;
}
[self.myCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:middleGoTo inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return kInfiniteCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
WeekdayCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"daycell" forIndexPath:indexPath];
cell.myLabel.text=[self.myCalendar weekdaySymbols][indexPath.item%7];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"sizeForItemAtIndexPath: %ld",indexPath.item);
return [(NSValue*)[dictOfSizes objectForKey:[self.myCalendar weekdaySymbols][indexPath.item%7]] CGSizeValue];
}
EDIT:
Few people mentioned using scrollview instead of collectionview for this.
Pretty much everywhere I researched for the circular scrollview, they recommended using a collectionview for this purpose as it's much easier. My real requirement is a bit more complex which requires me to use collectionview too.
Scrollview requires you to use the scrollViewDidScroll method and change the content offset each time. Plus it loads all views in memory at once as it doesn't have the advantage of reusing existing cells like collectionview does. So that's another memory hit.
The 7 weekdays is a simple example I used. If someone wants to show a lot of data (100), that would be a pretty bad implementation in scrollview and collectionview will present this bug.
ios objective-c swift uicollectionview uicollectionviewlayout
add a comment |
I am able to reproduce this on a very simple standalone app.
I have a collectionView which I want to make circular/loop so the elements repeat again and again (aka when user is at the last element in array, it shows the first element again after. And if they are at the first and scroll left, it shows the last element again). So it's a never ending collectionView.
So for a simple example, let's use days of week:
....Sunday, Monday, Tuesday, Wednesday..Saturday, Sunday, Monday....
In order to achieve this, I return a big number (10000) in the numberOfItemsInSection
and use indexPath.item%7
in the cellForItemAtIndexPath
method to adjust and get the correct element. Using %7
as there are 7 days.
My cells are very simple - just a UILabel in it.
This all works perfectly.
The issue comes with the sizeForItemAtIndexPath
. I want the cells to fit the label. As there would only be 7 actual size variations, so I pre-cache the sizes of the 7 days in a dictionary and return the correct size in sizeForItemAtIndexPath
method.
The problem is that (either due to a bug or intentional bad design by Apple of collectionview), the sizeForItemAtIndexPath
gets calls for every indexPath before the collectionview appears. So if I want to have the circular collectionView logic and need to return the big number (10000), it's is calling sizeForItemAtIndexPath
for all 10000 indexes. So there is a couple seconds lag until the collectionView appears. If I comment out the sizeForItemAtIndexPath
, then it works instantly. So that's definitely the issue. I put a NSLog
in the sizeForItemAtIndexPath
and it logs all the 22222 calls before load.
I have even defined the setEstimatedItemSize
, it still calls sizeForItemAtIndexPath
for all indexes.
I can reduce the lag by returning a smaller number 1000 but still, this is a bad design or bug for sure.
TableView doesn't have this bug - you can define a million rows and it only calls the heightForRow when it actually needs it. So I am not sure why collectionView needs to call it for all cells before showing, especially if setEstimatedItemSize
is already defined too.
Another side-effect of this bug is that the collectionView throws an error if I return a bigger value (50000 makes it break, 22222 is okay). It prints the error for too big values:
This NSLayoutConstraint is being configured with a constant that exceeds internal limits. A smaller value will be substituted, but this problem should be fixed. Break on BOOL _NSLayoutConstraintNumberExceedsLimit(void) to debug. This will be logged only once. This may break in the future.
TableView can easily handle huge values because it doesn't have this bug.
I have also tried disabling prefetching
but that had no effect.
What do you all think?
Relevant code:
#define kInfiniteCount 22222
#define kDayNameMargin 30
@interface ViewController (){
NSMutableDictionary *dictOfSizes;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
self.myCalendar = [NSCalendar currentCalendar];
[self.myCalendar setLocale:locale];
dictOfSizes = [NSMutableDictionary new];
for (int i=0; i<7; i++) {
WeekdayCollectionViewCell *sizingCell = [[NSBundle mainBundle] loadNibNamed:@"WeekdayCell" owner:self options:nil][0];
sizingCell.myLabel.text=[self.myCalendar weekdaySymbols][i];
[sizingCell layoutIfNeeded];
[dictOfSizes setObject:[NSValue valueWithCGSize:[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]] forKey:sizingCell.myLabel.text];
}
self.myCollectionView.decelerationRate = UIScrollViewDecelerationRateFast;
[self.myCollectionView registerNib:[UINib nibWithNibName:@"WeekdayCell" bundle:nil] forCellWithReuseIdentifier:@"daycell"];
[(UICollectionViewFlowLayout*)self.myCollectionView.collectionViewLayout setEstimatedItemSize:CGSizeMake(200, self.myCollectionView.frame.size.height)];
[self.myCollectionView reloadData];
NSInteger middleGoTo = kInfiniteCount/2;
while (![[self.myCalendar weekdaySymbols][middleGoTo%7] isEqualToString:@"Monday"]) {
middleGoTo--;
}
[self.myCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:middleGoTo inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return kInfiniteCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
WeekdayCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"daycell" forIndexPath:indexPath];
cell.myLabel.text=[self.myCalendar weekdaySymbols][indexPath.item%7];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"sizeForItemAtIndexPath: %ld",indexPath.item);
return [(NSValue*)[dictOfSizes objectForKey:[self.myCalendar weekdaySymbols][indexPath.item%7]] CGSizeValue];
}
EDIT:
Few people mentioned using scrollview instead of collectionview for this.
Pretty much everywhere I researched for the circular scrollview, they recommended using a collectionview for this purpose as it's much easier. My real requirement is a bit more complex which requires me to use collectionview too.
Scrollview requires you to use the scrollViewDidScroll method and change the content offset each time. Plus it loads all views in memory at once as it doesn't have the advantage of reusing existing cells like collectionview does. So that's another memory hit.
The 7 weekdays is a simple example I used. If someone wants to show a lot of data (100), that would be a pretty bad implementation in scrollview and collectionview will present this bug.
ios objective-c swift uicollectionview uicollectionviewlayout
I am able to reproduce this on a very simple standalone app.
I have a collectionView which I want to make circular/loop so the elements repeat again and again (aka when user is at the last element in array, it shows the first element again after. And if they are at the first and scroll left, it shows the last element again). So it's a never ending collectionView.
So for a simple example, let's use days of week:
....Sunday, Monday, Tuesday, Wednesday..Saturday, Sunday, Monday....
In order to achieve this, I return a big number (10000) in the numberOfItemsInSection
and use indexPath.item%7
in the cellForItemAtIndexPath
method to adjust and get the correct element. Using %7
as there are 7 days.
My cells are very simple - just a UILabel in it.
This all works perfectly.
The issue comes with the sizeForItemAtIndexPath
. I want the cells to fit the label. As there would only be 7 actual size variations, so I pre-cache the sizes of the 7 days in a dictionary and return the correct size in sizeForItemAtIndexPath
method.
The problem is that (either due to a bug or intentional bad design by Apple of collectionview), the sizeForItemAtIndexPath
gets calls for every indexPath before the collectionview appears. So if I want to have the circular collectionView logic and need to return the big number (10000), it's is calling sizeForItemAtIndexPath
for all 10000 indexes. So there is a couple seconds lag until the collectionView appears. If I comment out the sizeForItemAtIndexPath
, then it works instantly. So that's definitely the issue. I put a NSLog
in the sizeForItemAtIndexPath
and it logs all the 22222 calls before load.
I have even defined the setEstimatedItemSize
, it still calls sizeForItemAtIndexPath
for all indexes.
I can reduce the lag by returning a smaller number 1000 but still, this is a bad design or bug for sure.
TableView doesn't have this bug - you can define a million rows and it only calls the heightForRow when it actually needs it. So I am not sure why collectionView needs to call it for all cells before showing, especially if setEstimatedItemSize
is already defined too.
Another side-effect of this bug is that the collectionView throws an error if I return a bigger value (50000 makes it break, 22222 is okay). It prints the error for too big values:
This NSLayoutConstraint is being configured with a constant that exceeds internal limits. A smaller value will be substituted, but this problem should be fixed. Break on BOOL _NSLayoutConstraintNumberExceedsLimit(void) to debug. This will be logged only once. This may break in the future.
TableView can easily handle huge values because it doesn't have this bug.
I have also tried disabling prefetching
but that had no effect.
What do you all think?
Relevant code:
#define kInfiniteCount 22222
#define kDayNameMargin 30
@interface ViewController (){
NSMutableDictionary *dictOfSizes;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
self.myCalendar = [NSCalendar currentCalendar];
[self.myCalendar setLocale:locale];
dictOfSizes = [NSMutableDictionary new];
for (int i=0; i<7; i++) {
WeekdayCollectionViewCell *sizingCell = [[NSBundle mainBundle] loadNibNamed:@"WeekdayCell" owner:self options:nil][0];
sizingCell.myLabel.text=[self.myCalendar weekdaySymbols][i];
[sizingCell layoutIfNeeded];
[dictOfSizes setObject:[NSValue valueWithCGSize:[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]] forKey:sizingCell.myLabel.text];
}
self.myCollectionView.decelerationRate = UIScrollViewDecelerationRateFast;
[self.myCollectionView registerNib:[UINib nibWithNibName:@"WeekdayCell" bundle:nil] forCellWithReuseIdentifier:@"daycell"];
[(UICollectionViewFlowLayout*)self.myCollectionView.collectionViewLayout setEstimatedItemSize:CGSizeMake(200, self.myCollectionView.frame.size.height)];
[self.myCollectionView reloadData];
NSInteger middleGoTo = kInfiniteCount/2;
while (![[self.myCalendar weekdaySymbols][middleGoTo%7] isEqualToString:@"Monday"]) {
middleGoTo--;
}
[self.myCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:middleGoTo inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return kInfiniteCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
WeekdayCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"daycell" forIndexPath:indexPath];
cell.myLabel.text=[self.myCalendar weekdaySymbols][indexPath.item%7];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"sizeForItemAtIndexPath: %ld",indexPath.item);
return [(NSValue*)[dictOfSizes objectForKey:[self.myCalendar weekdaySymbols][indexPath.item%7]] CGSizeValue];
}
EDIT:
Few people mentioned using scrollview instead of collectionview for this.
Pretty much everywhere I researched for the circular scrollview, they recommended using a collectionview for this purpose as it's much easier. My real requirement is a bit more complex which requires me to use collectionview too.
Scrollview requires you to use the scrollViewDidScroll method and change the content offset each time. Plus it loads all views in memory at once as it doesn't have the advantage of reusing existing cells like collectionview does. So that's another memory hit.
The 7 weekdays is a simple example I used. If someone wants to show a lot of data (100), that would be a pretty bad implementation in scrollview and collectionview will present this bug.
ios objective-c swift uicollectionview uicollectionviewlayout
ios objective-c swift uicollectionview uicollectionviewlayout
edited Nov 23 '18 at 22:59
Tamás Sengel
26.6k146793
26.6k146793
asked Nov 23 '18 at 22:57
Pranoy CPranoy C
4,15583460
4,15583460
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
That's expected behaviour and it's not so much related to UICollectionView
- it is more UICollectionViewFlowLayout
that you use.
With each cell being different size, FlowLayout will request sizes for each cell separately, to calculate total size of CollectionView
- that is required to properly handle scrolling, scrollbars.
UITableView it's a bit simpler, as it's layout is much simpler (only height matters) - that's why it's possible to use estimatedSize there.
The whole Core Layout Process
is well explained here:
https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html
To overcome this problem I would recommend using your custom UICollectionViewLayout
and move your caching logic and reusing sizes for cells inside CollectionViewLayout
, not in your ViewController
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453681%2fsizeforitematindexpath-getting-called-for-all-indexes-before-load-i-am-pretty%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
That's expected behaviour and it's not so much related to UICollectionView
- it is more UICollectionViewFlowLayout
that you use.
With each cell being different size, FlowLayout will request sizes for each cell separately, to calculate total size of CollectionView
- that is required to properly handle scrolling, scrollbars.
UITableView it's a bit simpler, as it's layout is much simpler (only height matters) - that's why it's possible to use estimatedSize there.
The whole Core Layout Process
is well explained here:
https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html
To overcome this problem I would recommend using your custom UICollectionViewLayout
and move your caching logic and reusing sizes for cells inside CollectionViewLayout
, not in your ViewController
.
add a comment |
That's expected behaviour and it's not so much related to UICollectionView
- it is more UICollectionViewFlowLayout
that you use.
With each cell being different size, FlowLayout will request sizes for each cell separately, to calculate total size of CollectionView
- that is required to properly handle scrolling, scrollbars.
UITableView it's a bit simpler, as it's layout is much simpler (only height matters) - that's why it's possible to use estimatedSize there.
The whole Core Layout Process
is well explained here:
https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html
To overcome this problem I would recommend using your custom UICollectionViewLayout
and move your caching logic and reusing sizes for cells inside CollectionViewLayout
, not in your ViewController
.
add a comment |
That's expected behaviour and it's not so much related to UICollectionView
- it is more UICollectionViewFlowLayout
that you use.
With each cell being different size, FlowLayout will request sizes for each cell separately, to calculate total size of CollectionView
- that is required to properly handle scrolling, scrollbars.
UITableView it's a bit simpler, as it's layout is much simpler (only height matters) - that's why it's possible to use estimatedSize there.
The whole Core Layout Process
is well explained here:
https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html
To overcome this problem I would recommend using your custom UICollectionViewLayout
and move your caching logic and reusing sizes for cells inside CollectionViewLayout
, not in your ViewController
.
That's expected behaviour and it's not so much related to UICollectionView
- it is more UICollectionViewFlowLayout
that you use.
With each cell being different size, FlowLayout will request sizes for each cell separately, to calculate total size of CollectionView
- that is required to properly handle scrolling, scrollbars.
UITableView it's a bit simpler, as it's layout is much simpler (only height matters) - that's why it's possible to use estimatedSize there.
The whole Core Layout Process
is well explained here:
https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html
To overcome this problem I would recommend using your custom UICollectionViewLayout
and move your caching logic and reusing sizes for cells inside CollectionViewLayout
, not in your ViewController
.
edited Nov 24 '18 at 2:39
answered Nov 24 '18 at 1:57
Grzegorz KrukowskiGrzegorz Krukowski
10.6k32850
10.6k32850
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453681%2fsizeforitematindexpath-getting-called-for-all-indexes-before-load-i-am-pretty%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown