Gap bug between cells. ios6. UITableView - ios

I have some issues with dynamic cell height. you can see it on screen. Issues highlighted in red. I haven't this issues on IOS 7.
UPD.
heightForRowAtIndexPath method seem like this:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath {
Contact* contact = [contacts objectAtIndex: indexPath.row];
CGFloat height = 170.0f;
if (contact.name ==nil) {
height -=25.0f;
}
if (contact.phone ==nil) {
height -=25.0f;
}
if (contact.email==nil) {
height -=25.0f;
}
if (contact.address==nil) {
height -=40.0f;
}
return height;
}
But i dunno why it correctly work on iphone 5 with ios7 and not work on iphone 4 with ios6.1.
UPD2
layoutSubviews method:
-(void)layoutSubviews {
CGFloat phoneY = 65.0f;
CGFloat emailY = 90.0f;
CGFloat addressY = 115.0f;
CGRect contactNameLabelFrame = contactNameLabel.frame;
CGRect nameLabelFrame = nameLabel.frame;
CGRect phoneLabelFrame = contactPhoneLabel.frame;
CGRect phoneButtonFrame = phoneButton.frame;
CGRect emailButtonFrame = emailButton.frame;
CGRect emailLabelFrame = contactEmailLabel.frame;
CGRect addressLabelFrame = contactAddressLabel.frame;
CGRect addressButtonFrame = addressButton.frame;
if (contact.name == nil) {
contactNameLabelFrame.size.width = 0.0f;
nameLabelFrame.size.width = 0.0f;
phoneY -=25.0f;
emailY -= 25.0f;
addressY -= 25.0f;
} else {
contactNameLabelFrame.size.width = 60.0f;
nameLabelFrame.size.width = 212.0f;
}
if (contact.phone == nil) {
phoneLabelFrame.size.width = 0.0f;
phoneButtonFrame.size.width = 0.0f;
emailY -= 25.0f;
addressY -= 25.0f;
} else {
phoneLabelFrame.size.width = 60.0f;
phoneLabelFrame.origin.y = phoneY;
phoneButtonFrame.size.width = 212.0f;
phoneButtonFrame.origin.y = phoneY - 4;
}
if (contact.email == nil) {
emailLabelFrame.size.width = 0.0f;
emailButtonFrame.size.width = 0.0f;
addressY -= 25.0f;
} else {
emailLabelFrame.origin.y = emailY;
emailLabelFrame.size.width = 60.0f;
emailButtonFrame.origin.y = emailY - 4;
emailButtonFrame.size.width = 212.0f;
}
if (contact.address == nil) {
addressLabelFrame.size.width = 0.0f;
addressButtonFrame.size.width = 0.0f;
} else {
addressLabelFrame.origin.y = addressY;
addressLabelFrame.size.width = 60.0f;
addressButtonFrame.origin.y = addressY + 2;
addressButtonFrame.size.width = 212.0f;
}
[contactNameLabel setFrame:contactNameLabelFrame];
[nameLabel setFrame:nameLabelFrame];
[contactPhoneLabel setFrame:phoneLabelFrame];
[phoneButton setFrame:phoneButtonFrame];
[contactEmailLabel setFrame:emailLabelFrame];
[emailButton setFrame:emailButtonFrame];
[contactAddressLabel setFrame:addressLabelFrame];
[addressButton setFrame:addressButtonFrame];
}
UPD3
Thanks all. I found the source of the problem. I add to layoutSubviews method [super layoutSubviews];

Related

__block modifier creates unreadable memory

Now Im developing a banner showing feature in iOS
It's a singleton which shows banner on the upper part of screen when user logs in.
It's basically a shared view with a class method showWithName...
#interface XXUserWelcomeBanner ()
{
UIImageView *logoView;
UILabel *textLabel;
CGFloat _width;
}
#end
When user calls, it creates a UIImageView and a UILabel to add on self. And animates itself onto the screen.
+ (XXUserWelcomeBanner *)shared {
static dispatch_once_t onceToken;
static XXUserWelcomeBanner *userWelcomBanner;
dispatch_once(&onceToken, ^{
userWelcomBanner = [[XXUserWelcomeBanner alloc] init];
});
return userWelcomBanner;
}
+ (void)showWithUserName:(NSString *)userID andLogo:(UIImage * _Nullable)logo {
dispatch_async(dispatch_get_main_queue(), ^{
[[self shared] createWithName:userID andLogo:logo];
});
}
So there's this other bug I just found that causes this method to be called twice and on the second time it shows only the UIImageView.
And I don't understand why that's happening.
Because the UIImageView and UILabel won't be created twice.
Here's more code.
#pragma mark - private
- (void)createWithName:(NSString *)name andLogo:(UIImage * _Nullable)logo {
self.opaque = NO;
self.alpha = 0.9;
self.backgroundColor = COLOR(0xfcfcfc);
// if (#available(iOS 13.0, *)) {
// self.backgroundColor = UIColor.secondarySystemBackgroundColor;
// }
CGSize labelSize = CGSizeZero;
if (logoView == nil) {
if (logo != nil) {
logoView = [[UIImageView alloc] initWithImage:logo];
[self addSubview:logoView];
} else {
NSString *imagePath = [XXUtility pathForResourceNamed:#"Logo" withExtension:#"png"];
UIImage *imageToAdd = [[UIImage alloc] initWithContentsOfFile:imagePath];
logoView = [[UIImageView alloc] initWithImage:imageToAdd];
[self addSubview:logoView];
}
}
if (textLabel == nil) {
textLabel = [[UILabel alloc] init];
NSString * labelString = [NSString stringWithFormat:NSLocalizedStringWithDefaultValue(#"welcom banner", #"userInterface", [XXUtility bundleForStrings], #"Dear %#, welcome into game", #"user welcome banner text"), name];
labelSize = [labelString sizeWithAttributes:#{NSFontAttributeName : textLabel.font}];
textLabel.text = labelString;
[self addSubview:textLabel];
}
NSLog(#"XXUserWelcomeBanner Label size is %f x %f", labelSize.height, labelSize.width);
[self bannerSizeWithLabelSize:labelSize];
CGFloat bannerHeight = self.frame.size.height;
CGFloat bannerWidth = self.frame.size.width;
CGFloat logoHeight = bannerHeight * 0.45;
CGFloat logoWidth = logoHeight;
CGFloat logoXPos = (bannerWidth - logoWidth - labelSize.width) / 2;
CGFloat logoYPos = (bannerHeight - logoHeight) / 2;
CGFloat labelHeight = labelSize.height;
CGFloat labelWidth = labelSize.width;
CGFloat labelXPos = logoXPos + logoWidth + 5;
CGFloat labelYPos = (bannerHeight - labelHeight) / 2;
logoView.frame = CGRectMake(logoXPos, logoYPos, logoWidth, logoHeight);
textLabel.frame = CGRectMake(labelXPos, labelYPos, labelWidth, labelHeight);
[self bannerShow];
}
- (void)bannerSizeWithLabelSize:(CGSize)lSize {
_width = 40 + lSize.width + 5;
CGFloat height = 40;
CGFloat xPosition = ScreenWidth * 1/2 - _width * 1/2;
CGFloat yPosition = - height;
self.frame = CGRectMake(xPosition, yPosition, _width, height);
}
- (void)bannerShow {
UIViewController *vc;
if ([TOP_VIEWCONTROLLER respondsToSelector:#selector(topViewController)]) {
vc = [TOP_VIEWCONTROLLER topViewController];
} else {
vc = TOP_VIEWCONTROLLER;
}
[vc.view addSubview:self];
[UIView animateWithDuration:0.6 delay:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^{
CGFloat height = 40;
CGFloat xPos = ScreenWidth * 1/2 - self->_width * 1/2;
CGFloat yPos = height * 1/3 + KiPhoneXSafeAreaDValue;
self.frame = CGRectMake(xPos, yPos, self->_width, height);
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.6 delay:0.2 options:UIViewAnimationOptionCurveEaseIn animations:^{
CGFloat height = 40;
CGFloat xPosition = ScreenWidth * 1/2 - self->_width * 1/2;
CGFloat yPosition = - height;
self.frame = CGRectMake(xPosition, yPosition, self->_width, height);
} completion:^(BOOL finished) {
[self bannerDestroy];
self.alpha = 0;
}];
});
}];
}
- (void)bannerDestroy {
[logoView removeFromSuperview];
[textLabel removeFromSuperview];
logoView = nil;
textLabel = nil;
[self removeFromSuperview];
}
- (void)dealloc
{
//
NSLog(#"uiview dealloc");
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
#end
Thanks in advance.
It is expected that createWithName:andLogo: is calling more than once in your app. I guess you call it with different arguments, that's why it should not be inside dispatch_once(&onceToken, ^{ });. But you can optimise XXUserWelcomeBanner's init:
- (instancetype)init {
self = [super init];
if (self) {
logoView = [[UIImageView alloc] init];
[self addSubview:logoView];
textLabel = [[UILabel alloc] init];
[self addSubview:textLabel];
}
return self;
}
In createWithName:andLogo: you will have the following:
if (logo != nil) {
logoView.image = logo;
} else {
NSString *imagePath = [XXUtility pathForResourceNamed:#"Logo" withExtension:#"png"];
UIImage *imageToAdd = [[UIImage alloc] initWithContentsOfFile:imagePath];
logoView.image = imageToAdd;
}
NSString * labelString = [NSString stringWithFormat:NSLocalizedStringWithDefaultValue(#"welcom banner", #"userInterface", [XXUtility bundleForStrings], #"Dear %#, welcome into game", #"user welcome banner text"), name];
CGSize labelSize = [labelString sizeWithAttributes:#{NSFontAttributeName : textLabel.font}];
textLabel.text = labelString;

Cells order in UICollectionView

I need to create a UICollectionView with cells of different sizes (1x1, 2x2, 2x1, 3x2.5). I've already code to add cells depending on which size they are using collectionView:layout:sizeForItemAtIndexPath:.
Here is expected result (cells 1 and 3 have to be on the left of cell 2) :
But current result is :
My (ugly) current code is (self.cellSize = screen width / 3) :
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat size = self.cellSize;
if (indexPath.item == 0) {
return CGSizeMake(self.cellSize * 3.f, self.cellSize * 2.5f);
}
if (indexPath.item == 1) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 2) {
return CGSizeMake(self.cellSize * 2.f, self.cellSize * 2.f);
}
if (indexPath.item == 3) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 4) {
return CGSizeMake(self.cellSize * 2.f, self.cellSize);
}
if (indexPath.item == 5) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 6) {
return CGSizeMake(self.cellSize, self.cellSize);
}
if (indexPath.item == 7) {
return CGSizeMake(self.cellSize * 2.f, self.cellSize);
}
if (indexPath.item == 8) {
return CGSizeMake(self.cellSize * 3.f, self.cellSize * 2.5f);
}
return CGSizeMake(size, size);
}
Is there a way to specify that cell 3 has to be above cell 1, but on left of cell 2 ?
I don't want to do a static layout that will not change because each cell could be of different size in future. For example, cell 2 could be 2x1 sized ...
Which is the best approach to do that ? I was expecting to specify to UICollectionViewLayout a flow (like "from top"), but it doesn't work like that ...
A sample example by subclassing UICollectionViewLayout.
All values are hard coded, just to explicit the logic behind it. Of course, that could be optimized.
#interface CustomCollectionViewLayout ()
#property (nonatomic, strong) NSMutableDictionary *cellLayouts;
#property (nonatomic, assign) CGSize unitSize;
#end
#implementation CustomCollectionViewLayout
-(id)initWithSize:(CGSize)size
{
self = [super init];
if (self)
{
_unitSize = CGSizeMake(size.width/3,150);
_cellLayouts = [[NSMutableDictionary alloc] init];
}
return self;
}
-(void)prepareLayout
{
for (NSInteger i = 0; i < [[self collectionView] numberOfItemsInSection:0]; i ++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
CGRect frame;
switch ([indexPath item])
{
case 0:
frame = CGRectMake(0, 0, _unitSize.width*3, _unitSize.height*2.5);
break;
case 1:
frame = CGRectMake(0, _unitSize.height*2.5, _unitSize.width, _unitSize.height);
break;
case 2:
frame = CGRectMake(_unitSize.width, _unitSize.height*2.5, _unitSize.width*2, _unitSize.height*2);
break;
case 3:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height, _unitSize.width, _unitSize.height);
break;
case 4:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height+_unitSize.height, _unitSize.width*2, _unitSize.height);
break;
case 5:
frame = CGRectMake(_unitSize.width*2, _unitSize.height*2.5+_unitSize.height+_unitSize.height, _unitSize.width, _unitSize.height);
break;
case 6:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height+_unitSize.height+_unitSize.height, _unitSize.width, _unitSize.height);
break;
case 7:
frame = CGRectMake(_unitSize.width, _unitSize.height*2.5+_unitSize.height+_unitSize.height+_unitSize.height, _unitSize.width*2, _unitSize.height);
break;
case 8:
frame = CGRectMake(0, _unitSize.height*2.5+_unitSize.height+_unitSize.height+_unitSize.height+_unitSize.height, _unitSize.width*3, _unitSize.height*2.5);
break;
default:
frame = CGRectZero;
break;
}
[attributes setFrame:frame];
[[self cellLayouts] setObject:attributes forKey:indexPath];
}
}
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *retAttributes = [[NSMutableArray alloc] init];
for (NSIndexPath *anIndexPath in [self cellLayouts])
{
UICollectionViewLayoutAttributes *attributes = [self cellLayouts][anIndexPath];
if (CGRectIntersectsRect(rect, [attributes frame]))
{
[retAttributes addObject:attributes];
}
}
return retAttributes;
}
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [self cellLayouts][indexPath];
}
-(CGSize)collectionViewContentSize
{
return CGSizeMake(_unitSize.width*3, _unitSize.height*9);
}
#end
Then, you just have to call :
CustomCollectionViewLayout *layout = [[CustomCollectionViewLayout alloc] initWithSize:self.myCollectionView.bounds.frame.size];
[self.myCollectionView setCollectionViewLayout:layout];
Rendering :
Here it's the same logic as Larme suggested. But with less hardcode and which give you the possibility of setting the number of items you want without adding new case:.
I call "pattern" a set of 5 items. So first I define constant values:
#define MAX_COLUMN 3 // Max columns in the pattern
#define MAX_LINE_PER_PATTERN 3 // Max lines in the pattern
#define PATTERN_ITEM_COUNT 5 // Max items in the pattern
Then I create a custom layout with 2 properties NSMutableArray *layoutAttributes and CGFloat contentHeight in which I need to override the methods:
- (void)prepareLayout{
[super prepareLayout];
if (!self.layoutAttributes){
self.layoutAttributes = [[NSMutableArray alloc] init];
CGFloat cellWidth = self.collectionView.frame.size.width / MAX_COLUMN;
CGFloat cellHeight = cellWidth;
self.contentHeight = 0.f;
for (int item = 0 ; item < [self.collectionView numberOfItemsInSection:0] ; item ++){
CGFloat width, height = 0.f;
CGFloat xPos, yPos = 0.f;
NSInteger patternCount = (NSInteger)((CGFloat)item / (CGFloat)PATTERN_ITEM_COUNT);
NSInteger currentIndex = item % PATTERN_ITEM_COUNT;
switch (currentIndex) {
case 0:
{
xPos = 0.f;
yPos = 0.f + MAX_LINE_PER_PATTERN * cellHeight * patternCount;
width = cellWidth;
height = cellHeight;
self.contentHeight += cellHeight;
break;
}
case 1:
{
xPos = cellWidth;
yPos = 0.f + MAX_LINE_PER_PATTERN * cellHeight * patternCount;
width = cellWidth * 2.f;
height = cellHeight * 2.f;
self.contentHeight += cellHeight;
break;
}
case 2:
{
xPos = 0.f;
yPos = cellHeight + MAX_LINE_PER_PATTERN * cellHeight * patternCount;
width = cellWidth;
height = cellHeight;
break;
}
case 3:
{
xPos = 0.f;
yPos = 2.f * cellHeight + MAX_LINE_PER_PATTERN * cellHeight * patternCount;
width = cellWidth * 2.f;
height = cellHeight;
self.contentHeight += cellHeight;
break;
}
case 4:
{
xPos = 2.f * cellWidth;
yPos = 2.f * cellHeight + MAX_LINE_PER_PATTERN * cellHeight * patternCount;
width = cellWidth;
height = cellHeight;
break;
}
default:
NSLog(#"error with index");
break;
}
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForRow:item inSection:0]];
attr.frame = CGRectMake(xPos,
yPos,
width,
height);
[self.layoutAttributes addObject:attr];
}
}
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
NSMutableArray *currentAttributes = [NSMutableArray new];
for (UICollectionViewLayoutAttributes *attr in self.layoutAttributes) {
if (CGRectIntersectsRect(attr.frame, rect))
{
[currentAttributes addObject:attr];
}
}
return currentAttributes;
}
- (CGSize)collectionViewContentSize{
return CGSizeMake(self.collectionView.frame.size.width, self.contentHeight);
}
Then assign this custom layout to self.collectionView.collectionViewLayout and that's it. You can find more information and swift version here.

UICollectionView find center cell when content inset is used

I'm trying to figure out how to find the center most cell of my UICollectionView, which is set to only scroll horizontally.
I tried this SO: how to get indexPath for cell which is located in the center of UICollectionView but it isn't working out, I think because I'm using the contentInset property of my UICollectionView.
What I'm doing is setting the contentInset left and right of the flow layout to exactly 1/2 of self.view's bounds width minus 1/2 of itemSize width. I'm not sure how to calculate the center most cell due to this. I'd appreciate any help offered. Code:
CGPoint cellCenter = CGPointMake((self.collectionView.center.x +
self.collectionView.contentOffset.x) -
(self.sampleFlowLayout.sectionInset.left +
self.sampleFlowLayout.sectionInset.right), self.collectionView.center.y);
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:cellCenter];
if (indexPath)
{
NSInteger tag = [self.collectionView cellForItemAtIndexPath:indexPath].tag;
if (tag != self.currentSample)
{
self.currentSample = tag;
self.imageView.image = [self sampleImageWithOption:self.currentSample];
}
}
- (void)viewDidLoad
{
self.sampleFlowLayout = [[UICollectionViewFlowLayout alloc]init];
CGSize itemSize = CGSizeMake(63, 63);
self.sampleFlowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sampleFlowLayout.sectionInset = UIEdgeInsetsMake(0, (self.view.bounds.size.width / 2) - (itemSize.width / 2), 0, (self.view.bounds.size.width / 2) - (itemSize.width / 2));
}
I figured this out myself using help from this answer: https://stackoverflow.com/a/22696037/1533438
Final code:
- (void)snapCollectionView:(UICollectionView *)collectionView withProposedOffset:(CGPoint)proposedOffset
{
CGRect cvBounds = collectionView.bounds;
CGFloat halfWidth = cvBounds.size.width * 0.5;
CGFloat proposedContentOffsetCenterX = proposedOffset.x + halfWidth;
NSArray *attributesArray = [collectionView.collectionViewLayout layoutAttributesForElementsInRect:cvBounds];
UICollectionViewLayoutAttributes *candidateAttributes;
for (UICollectionViewLayoutAttributes *attributes in attributesArray)
{
if (attributes.representedElementCategory !=
UICollectionElementCategoryCell)
{
continue;
}
if (!candidateAttributes)
{
candidateAttributes = attributes;
continue;
}
if (fabsf(attributes.center.x - proposedContentOffsetCenterX) <
fabsf(candidateAttributes.center.x - proposedContentOffsetCenterX))
{
candidateAttributes = attributes;
}
}
CGPoint offset = CGPointMake(candidateAttributes.center.x - halfWidth, proposedOffset.y);
[collectionView setContentOffset:offset animated:YES];
CGPoint cellCenter = CGPointMake(offset.x + self.sampleCollectionView.bounds.size.width / 2.0, self.sampleCollectionView.bounds.size.height / 2.0);
NSIndexPath *indexPath = [self.sampleCollectionView indexPathForItemAtPoint:cellCenter];
if (indexPath)
{
NSInteger tag = [self.sampleCollectionView cellForItemAtIndexPath:indexPath].tag;
if (tag != self.currentSample)
{
self.currentSample = tag;
UIImage *image;
if (self.currentSample == 0)
{
image = self.image;
}
else
{
image = [self sampleImageWithOption:self.currentSample];
}
dispatch_async(dispatch_get_main_queue(),
^{
self.imageView.image = image;
});
}
}
}

iOS UILabel cannot resize the text

I would like to implement the ULLabelExtended to autosize the text size of the UILabel to the device width. but when it comes to the execution; it shows the picture as the result instead of showing the full clause:
The full clause : Ze aangeplant cocos rond hun nieuwe home.
Are there any other alternatives to get the relationship or functions that text size of label is proportional to the device width ?
The below is my code
Application:
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
[self.labelLong setWidthOfLabelWithMaxWidth:screenWidth];
[self.labelShort setWidthOfLabelWithMaxWidth:screenWidth];
Source:
#import "UILabelExtended.h"
#implementation UILabelExtended
#synthesize selector,customDelegate, objectInfo;
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(self.selector)
if([self.customDelegate respondsToSelector:self.selector]) {
[self.customDelegate performSelector:self.selector withObject:self];
return;
}
}
- (void)dealloc {
self.customDelegate = nil;
self.selector = NULL;
self.objectInfo = nil;
}
#end
#implementation UILabel(UILabelCategory)
- (void)setHeightOfLabel {
UILabel* label = self;
//get the height of label content
CGFloat height = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, 99999) lineBreakMode:NSLineBreakByWordWrapping].height;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
frame.size.height = height;
}
else {
frame.size.height = 0;
}
label.frame = frame;
}
- (void)setWidthOfLabel {
UILabel* label = self;
//get the height of label content
CGFloat width = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(99999, label.bounds.size.height) lineBreakMode:NSLineBreakByWordWrapping].width;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
frame.size.width = width+5;
}
else {
frame.size.width = 0;
}
label.frame = frame;
}
- (void)setHeightOfLabelWithMaxHeight:(float)maxHeight {
UILabel* label = self;
//get the height of label content
CGFloat height = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, maxHeight) lineBreakMode:NSLineBreakByWordWrapping].height;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
if (height > maxHeight) {
frame.size.height = maxHeight;
}
else {
frame.size.height = height;
}
}
else {
frame.size.height = 0;
}
label.frame = frame;
}
- (void)setWidthOfLabelWithMaxWidth:(float)maxWidth {
UILabel* label = self;
//get the height of label content
CGFloat width = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(99999, label.bounds.size.height) lineBreakMode:NSLineBreakByWordWrapping].width;
//set the frame according to calculated height
CGRect frame = label.frame;
if([label.text length] > 0) {
if (width > maxWidth) {
frame.size.width = maxWidth;
}
else {
frame.size.width = width;
}
}
else {
frame.size.width = 0;
}
label.frame = frame;
}
#end

AQGridview images are resizing after scrolling down

I'm using AQGridview for displaying my images inside a Gridview.
Every works oké, but when I scroll down my images are resized. (see screenshots)
This is what I do in my ViewController
- (AQGridViewCell *) gridView: (AQGridView *) aGridView cellForItemAtIndex: (NSUInteger) index
{
static NSString * PlainCellIdentifier = #"PlainCellIdentifier";
AQGridViewCell * cell = nil;
ImageDemoGridViewCell * plainCell = (ImageDemoGridViewCell *)[aGridView dequeueReusableCellWithIdentifier: PlainCellIdentifier];
if ( plainCell == nil )
{
plainCell = [[ImageDemoGridViewCell alloc] initWithFrame: CGRectMake(0.0, 0.0, 75, 75)
reuseIdentifier: PlainCellIdentifier];
}
Photo *photo = [_imageNames objectAtIndex:index];
plainCell.image = [NSString stringWithFormat:#"http://sportifun2014.sanmax.be/images/albums_photos/big/%#",photo.pho_filename];
cell = plainCell;
return cell ;
}
- (CGSize) portraitGridCellSizeForGridView: (AQGridView *) aGridView
{
return ( CGSizeMake(75, 89.9) );
}
And this is my Custom Cell class
- (id) initWithFrame: (CGRect) frame reuseIdentifier: (NSString *) aReuseIdentifier
{
self = [super initWithFrame: frame reuseIdentifier: aReuseIdentifier];
if ( self == nil )
return ( nil );
_imageView = [[UIImageView alloc] initWithFrame: CGRectZero];
[self.contentView addSubview: _imageView];
return ( self );
}
- (void) setImage: (NSString *) strurl
{
[_imageView setImageWithURL:[NSURL URLWithString:strurl]
placeholderImage:[UIImage imageNamed:#"menu"]];
[self setNeedsLayout];
}
- (void) layoutSubviews
{
NSLog(#"layoutSubviews");
[super layoutSubviews];
CGSize imageSize = _imageView.image.size;
CGRect frame = _imageView.frame;
CGRect bounds = self.contentView.bounds;
if ( (imageSize.width <= bounds.size.width) &&
(imageSize.height <= bounds.size.height) )
{
return;
}
// scale it down to fit
CGFloat hRatio = bounds.size.width / imageSize.width;
CGFloat vRatio = bounds.size.height / imageSize.height;
CGFloat ratio = MAX(hRatio, vRatio);
frame.size.width = floorf(imageSize.width * ratio);
frame.size.height = floorf(imageSize.height * ratio);
frame.origin.x = floorf((bounds.size.width - frame.size.width) * 0.5);
frame.origin.y = floorf((bounds.size.height - frame.size.height) * 0.5);
_imageView.frame = frame;
}
I've set changed this:
frame.size.width = floorf(imageSize.width * ratio);
frame.size.height = floorf(imageSize.height * ratio);
to this
frame.size.width = 75;
frame.size.height = 75;

Resources