UICollectionView layout issue on iOS7 - ipad

I am developing an app that supports iOS7 and iOS8. On iOS8 running on an iPad 2 the app runs fine. No issues. However on iOS7 there is an issue with one of my UICollectionView's which I just can't seem to fix. I am using AutoLayout and out of desperation, have tried springs and struts which made no difference.
So this is how the cell looks at 320 width:
Here are the AutoLayout constraints applied to the UICollectionView
And here is what happens when its on an iPad with iOS 7.1
Whatever I try I always get the same result on iOS7. On iOS8 with an iPad the cell displayed perfectly fine.
Not sure what is going on here.

Right, so I found the answer incase anyone else suffers the same issue.
The accepted answer from this SO question: Auto layout constraints issue on iOS7 in UITableViewCell
Actually helped me.
Here is what i did in my UICollectionViewCell's subclass:
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self){
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
return self;
}
return nil;
}
This solved the issue for me.

Related

Did they add more padding to UITableVIew in iOS 11?

Is it just me or they added a lot more padding to section headers and footers of grouped UITableViews in iOS 11?
I compiled my app to run with iOS 11 and noticed the extra padding.
I kinda solved it by setting contentInset.top to a negative value checking if the os is iOS 11, but this is a ugly workaround.
Is there any other better way do clear the extra padding of grouped table views in order to achieve the same results across all supported iOS? It kinda stinks to have multiple checks for such a silly thing.
Screenshot for comparison:
As you can see, on iOS 11 there's extra spacing between sections (yeah, those are sections!).
This is new contentInsetAdjustmentBehavior parameter of UIScrollView which you can set it as .never to prevent extra padding
if #available(iOS 11.0, *) {
tableView.contentInsetAdjustmentBehavior = .never
}
or in storyboard under Size Inspector
In iOS 11 the section footer has a view that adds to the spacing between the sections. You would need to set the view of the footer to nil explicitly in addition to adjusting the height for the footer:
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return nil;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0.1;
}
This will make your table view to look like what you had in iOS 10 and would also not have any effect on previous versions of iOS. You can do the same for the header if you don't need the headers.
You just need to set the table view's header and footer view.
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return [[UIView alloc] init];
}
- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [[UIView alloc] init];
}
I had a similar problem I think it was a bug in the Old Xcode.
If you are using autolayout and you have Content View and views inside this, Constrain to margins didn't work in Xcode 8, now fixed in xCode 9. You have to go in redo your constraints and uncheck the box on the View inside all table view cells. This will then be consistent on all ios 10 and ios 11 devices.
I solved my problem by setting the header and footer height in Storyboard.
Apparently, in Xcode 9 these are the default values when you create a UITableView
I tried to set them to 0, but 1 is the minimum and that solved the problem. Also, I checked how it behaves if the automatic is checked and it works as well.
Also, I don't know is it a bug or something, but I couldn't do it on existing table. I needed to delete it and drag it to UIViewController again.
If rashid's answer didn't work with setting the contentInsetAdjustmentBehavior to never then try the following:
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0
self.tableView.estimatedSectionFooterHeight = 0
iOS 11 Floating TableView Header
With my .grouped UITableView I was facing the same issue in iOS 11, it worked fine when I was using a UITableViewController, but not in UIViewController, following worked in my case:
tableView.estimatedSectionHeaderHeight = 0
Without above line tableView(heightForHeaderInSection never gets called.
It seems like a bug in iOS 11.

Xcode 6.1+ iOS SDK 8.1 UITableView

I have one problem regarding UITableview running with Xcode 6.1 + iOS SDK 8.1.
I have one simple single view application, something strange happened when i was using storyboard to create a tableview.
Inside of my viewDidLoad, I wrote this code:
UITableView *tableView = (id)[self.view viewWithTag:1];
[tableView registerClass:[NameAndColorCell class] forCellReuseIdentifier:CellIdentifier];
added/edited:
UITableView *tableView = (id)[self.view viewWithTag:1];
NSLog(#"Table View Tag = %ld", (long)tableView.tag);
[tableView registerClass:[NameAndColorCell class] forCellReuseIdentifier:CellIdentifier];
UIEdgeInsets contentInset = tableView.contentInset;
contentInset.top = 20;
[tableView setContentInset:contentInset];
But the tableView is always nil, and eventually caused my App crashed.
I checked with my View Controller's View, both "Use Auto Layout" and "Use Size Classes" were enabled.
After I disabled "Use Size Classes", everything went back normal. I mean, tableView was created successfully.
Has anyone met the same issue? Is this a bug from Xcode? or I made some mistake?
Please help me, Thanks a lot !
Best Regards,
Rui

How can a get the auto layout size of the UICollectionViewCells in iOS 8? (systemLayoutSizeFittingSize returns size with zero height in iOS 8)

Since iOS 8 [UIColletionViewCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] returns a size with height of 0.
Here's what the code does:
To determine the size for cell in a UICollectionView in iOS 7 I use systemLayoutSizeFittingSize: on a cell defined in a xib file using auto layout. The size depends on the font size of an UILabel being a subview of the UICollectionViewCell in my xib file. The label's font is set to UIFontTextStyleBody. So basically the cell's size depends on the font size setting made in iOS 7.
Here is the code itself:
+ (CGSize)cellSize {
UINib *nib = [UINib nibWithNibName:NSStringFromClass([MyCollectionViewCell class]) bundle:nil];
// Assumption: The XIB file only contains a single root UIView.
UIView *rootView = [[nib instantiateWithOwner:nil options:nil] lastObject];
if ([rootView isKindOfClass:[MyCollectionViewCell class]]) {
MyCollectionViewCell *sampleCell = (MyCollectionViewCell*)rootView;
sampleCell.label.text = #"foo"; // sample text without bar
[sampleCell setNeedsLayout];
[sampleCell layoutIfNeeded];
return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
}
return CGSizeZero;
}
It works perfectly fine in iOS 7 but not in iOS 8. Unfortunately I have no clue why.
How can I get the auto layout size of the UICollectionViewCells in iOS 8?
PS: Using
return [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
instead of
return [sampleCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
as somebody might suggest, doesn't make any difference.
What you need to do is wrap all of your content in a container view, then call:
return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
Your cell should look like this: cell -> containerView -> sub views
This works on both ios7 & ios8.
Supposedly on ios8, all you have to do is set the estimateSize & cell will automatically auto size on its own. Apparently that's not working as of beta 6.
Looks like this officially a bug: I filed a report that was closed as a duplicate of this one
Will report back when Beta 6 is out.
[Update: working properly in the GM seed of iOS 8, and the bug has been closed by Apple.]
We're using a work-around for now, copied below. Hopefully, these issues will be resolved before iOS 8 release and we can remove this. (The kludge assumes knowledge of Apple's implicit contentView behavior, and we have to hack IB outlet references to any constraints we transfer.)
We notice they're also removing all autoresizingMasks from storyboards/NIBs during upgrade, which makes sense given it's supposed to be auto-layout, but collection views still throwback to springs & struts. Perhaps this has been overlooked in the purge?
--Dan
/**
Kludge around cell sizing issues for iOS 8 and deployment to iOS 7 when compiled for 8. Call this on the collection view cell before it is used, such as in awakeFromNib. Because this manipulates top-level constraints, any references to such initial constraints, such as from IB outlets, will be invalidated.
Issue 1: As of iOS 8 Beta 5, systemLayoutSizeFittingSize returns height 0 for a UICollectionViewCell. In IB, cells have an implicit contentView, below which views placed in IB as subviews of the cell are actually placed. However, constraints set between these subviews and its superview are placed on the cell, rather than the contentView (which is their actual superview). This should be OK, as a constraint among items may be placed on any common ancestor of those items, but this is not playing nice with systemLayoutSizeFittingSize. Transferring those constraints to be on the contentView seems to fix the issue.
Issue 2: In iOS 7, prior to compiling against iOS 8, the resizing mask of the content view was being set by iOS to width+height. When running on iOS 7 compiled against iOS 8 Beta 5, the resizing mask is None, resulting in constraints effecting springs for the right/bottom margins. Though this starts out the contentView the same size as the cell, changing the cell size, as we do in the revealing list, is not tracked by changing it's content view. Restore the previous behavior.
Moving to dynamic cell sizing in iOS 8 may circumvent this issue, but that remedy isn't available in iOS 7.
*/
+ (void)kludgeAroundIOS8CollectionViewCellSizingIssues:(UICollectionViewCell *)cell {
// transfer constraints involving descendants on cell to contentView
UIView *contentView = cell.contentView;
NSArray *cellConstraints = [cell constraints];
for (NSLayoutConstraint *cellConstraint in cellConstraints) {
if (cellConstraint.firstItem == cell && cellConstraint.secondItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:contentView attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:cellConstraint.secondItem attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
} else if (cellConstraint.secondItem == cell && cellConstraint.firstItem) {
NSLayoutConstraint *parallelConstraint = [NSLayoutConstraint constraintWithItem:cellConstraint.firstItem attribute:cellConstraint.firstAttribute relatedBy:cellConstraint.relation toItem:contentView attribute:cellConstraint.secondAttribute multiplier:cellConstraint.multiplier constant:cellConstraint.constant];
parallelConstraint.priority = cellConstraint.priority;
[cell removeConstraint:cellConstraint];
[contentView addConstraint:parallelConstraint];
}
}
// restore auto-resizing mask to iOS 7 behavior
contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
}
This is a bug in xCode6 and iOS 8 SDK running on iOS7 devices :)
It almost waisted my day. Finally it worked with the below code in the UICollectionViewCell sub class. I hope this will be fixed with the next version
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
self.contentView.frame = bounds;
}
I had the same issue for UITableViewCells and iOS 7 (ios8 works perfectly), but "Triet Luong" solution worked for me:
return [sampleCell.containerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
This is not a bug, I have been grappling with this issue now for some time and have tried different things, I am giving below the steps that's worked for me:
1) use contentView [sampleCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
2) you can create your own contentView and have the subViews added to the contentView, don't forget to pin the top, bottom and left and right of the contentView if you are using a custom contentView to the superView, if you don't do this then height will be 0, here also depending upon your requirements you can for. e.g not pin the bottom of the contentView to the superView so that the height of the view can vary, but pinning is important and pinning which one depends on your requirements.
3) set the constraints properly in interface builder depending upon your requirements, there are certain constraints that cannot be added in interface builder, but then you can add them in viewDidLoad of the viewController.
So my 2 cents input is that constraints have to be set properly in the interface builder for systemLayoutSizeFittingSize:UILayoutFittingCompressedSize to return correct dimensions, this is the solution guys.
maybe you have some wrong constrain, you should specify both virtical top space and bottom space between your UIView and contentView, i also had this issue before, that is because i just specified the virtical top space, and didn't specfied the virtical bottom space to contentView
It was a bug in iOS 8 beta versions. Finally it is fixed with for iOS 8 GB (Build 12A365). So for me now it works with the same code I wrote for iOS 7. (see the question)

Cannot set clipToBounds on UITableViewCell's contentView in iOS 7.1

The iOS 7 redesign resulted in change of the view hierarchy of UITableViewCells. The content view of the cell was wrapped in a private class called UITableViewCellScrollView.
In iOS 7 UITableViewCellScrollView has clipsToBounds set to YES and UITableViewCellContentView has clipToBounds set to NO.
In iOS 7.1 UITableViewCellScrollView has clipsToBounds set to NO and UITableViewCellContentView has clipToBounds set to NO.
If you call [[self contentView] setClipsToBounds:YES] in iOS 7.1 is does it stick. By the time layoutSubviews is called on the cell UITableViewCellContentView has clipToBounds set to NO again.
[[self contentView] superview] setClipsToBounds:YES] works in iOS 7.1 and sets UITableViewCellScrollView's clipToBounds to YES but this is a very brittle solution.
Overriding layoutSubview on the cell and calling [[self contentView] setClipsToBounds:YES] works but is another fraile solution.
Does anyone know why this change has been made and a more robust solution to it?
As discussed in the comments, the only solution right now in iOS7.1 is to set clipsToBounds on the cell itself.
It's quite annoying. What I did is add an UIView in the contentView with identical size (and autoresizingMask in width), add the relevant content to this view, and set clipsToBounds to it.
I hit the some problem, and I solved this confused problem by an ugly way finally.
// Create a subclass of UITableView
// Then override setClipsToBounds:
- (void)setClipsToBounds:(BOOL)clipsToBounds {
[super setClipsToBounds:YES];
}
In iOS 8, checking the cell's "Clip Subviews" in the XIB did not work.
What does work is:
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
self.clipsToBounds = YES;
}

UICollectionView unresponsive to swipe on the right w-h pixels in landscape mode

I have a UICollectionView that I am populating with several cells and a custom flow layout. This works great in portrait mode. When I rotate to landscape I encounter an issue where I can't swipe up/down on the right portion of the screen. It seems to be the right w-h pixels which are unresponsive to touch. The collection view does draw cells properly and everything else seems normal. Also, if I begin a swipe in the working zone and go diagonally into the unresponsive area, the drag continues to work.
When the device is rotated, I make the following calls:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
_currentIndex = self.assetsCollectionView.contentOffset.y / self.assetsCollectionView.bounds.size.height;
[self.assetsCollectionView.collectionViewLayout invalidateLayout];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
float y = _currentIndex * self.assetsCollectionView.bounds.size.height;
[self.assetsCollectionView setContentOffset:CGPointMake(0, y) animated:NO];
}
These look fine to me, and when I comment them out completely, I get the same behavior.
Other details: The UICollectionView is the only UI component in my View Controller, except for a small detail label which I'm sure is not the issue.
I'm switching between two subclasses of UICollectionViewFlowLayout so that the cells can expand to full screen and back, but I'm experiencing the same problem no matter which layout, or even before I swap them out. One more detail is that the fullscreen layout is pageEnabled while the smaller one is not.
The containing UIViewController is inside a UITabController.
One more note: I've double checked my layout constraints to ensure there isn't funny business there either.
Any ideas?
I had exactly the same problem. After spending an evening trying to figure out what was wrong I managed to solve it by adding these two lines in viewDidLoad method of the CollectionView view controller class. (I do not use autolayout)
self.view.autoresizesSubviews = YES;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
I hope that this solves your issue too.

Resources