UICollectionView clipsToBounds is not working properly with paging - ios

I am using UICollectionView with horizontal paging enabled. My collectionView frame is less than the screen size.
I used the following code :
myCollectionView.clipsToBounds=FALSE;
Still I am not able to see the views outside the bounds of my collectionView.
I am using custom UICollectionViewLayout

If the size of each page is greater or equal to your collectionView's frame size, you will not be able to see the content outside the frame even clipToBounds is disabled.
In order to save the memory, the cells in the collectionView are reusable and will be removed if they are out of the frame (i.e. only shows the visible cells).
To recreate the effects like the one seen on the App Store:
Try to set the frame of the collectionView as large as your collectionView's superView, and specify proper minimumLineSpacing for your UICollectionViewFlowLayout.
You may like to take a look at this post about targetContentOffsetForProposedContentOffset:withScrollingVelocity which gives you controls to decide the contentOffset of a given page.

I'm not sure but may be the problem when you init your collectionView it's initializing with the some default settings like clipToBounds. Try this method to layout subviews:
-(void)layoutSubviews{
[super layoutSubviews];
myCollectionView.clipsToBounds = FALSE;
}
Hope it works.

Related

When is it safe to retrieve image height in iOS

I've got a table cell. Within it I've got an image that has a height constraint of 25% of the screen size.
When is the proper time to retrieve the image height using
imageView.frame.height
to make sure that it has been resized according to the constraint? In general i am a little confused as to when the time to retrieve the element heights (images, labels ) is in the lifecycle. I need this information to add up with all the other element heights for a cell so i can tell a table what the row size is using the heightForRow method.
P.S: I cannot use UITableViewAutomaticDimension as one of the elements is a webview and i can only retrieve its height after the webview delegate method completes and has loaded a webpage.
If you are using autolayotus, you can get imageView or any other UIElements frames in viewDidLayoutSubViews or in viewDidAppear. These life cycle methods will be called while/after applying constraints.
You can always subclass UIImageView and override methods setFrame and setBounds to met your needs.

Autolayout scrollview with collectionview

I have been struggling with this for a few days now, and I am looking to see if someone can help me with this AutoLayout problem.
In my iOS7 application, I have a UIView that has a UIScrollView and inside it a UIView(container) with some elements positioned. I have in there, a UIImageView, UITableView, UICollectionView, UITextView and a MapView. There is no height constraint on the UIScrollView and the container UIView. There are no height constraints on the UICollectionView and the UITextView.
What I want to accomplish is
The UITextview should expand to the content size as in all the text should appear without any vertical scrolling enabled for the UITextView.
The UICollectionView should always show all items and there should not be any scrolling enabled there as well.
Overall, I want a UIScrollView with items in it, that scale based on content. I have tried numerous things, but failed.
If anyone has pointers or suggestions on how to go about doing this, it would be very helpful.
OK, I would go about this in a completely different way.
First, get rid of the scrollView completely.
Just use a UICollectionView for this entire interface.
The UICollectionView can take a UIView for a section header. Make this UIView with your UITextView inside. You will need to manually calculate the correct height for your UITextView (and UIView).
Something like...
CGSize size = [theText sizeWithFont:<the font used> constrainedToSize:CGSizeMake(desiredWidth, CGFLOAT_MAX)];
Then just populate your collection view.
By doing this your collection view will control all the scrolling. Because you have set the textview to the correct size in the header you will have all the text there.
This is how I would go about it:
I assume your issue is with the height of the views, that affect the scrolling.
In the textViewDidChange: I would set the frame of the UITextView same as it's contentSize. When they are both the same, scrolling gets disabled.
After populating your UITableView and calling reloadData, I would set it's frame same as it's contentSize.
The mapView (MKMapView, I suppose) has the same frame throughout, I suppose. So you just use it's fixed height. If it changes height, you must store it's changing height each time it changes.
Once you have all the heights, add them up, and set the frame of the outer view same as then combined height of the inner view. Iterate this to all nested views, beginning from innermost views, and moving to outer views.
The catch here is, every time your content changes, the frames have to be resized. Hence changing the frames in textViewDidChange:, after reloadData, etc makes sense.
EDIT : One thing you might want to do first is, getting rid of redundant views. Your view hierarchy seems Rube Goldberg to me. The lesser views you have, the lesser work you will have to do.
Ok.. so I solved this problem by creating a IBOutlet for my NSLayoutConstraint on the UITextView in question.
I simply computed the height and then applied it on the constraint and it worked..
#Fogmeister - Your solution will also work, but it would require me to rewire a whole UI page.. Your approach is definitely a feasible one and shall keep in mind for future iOS apps..

UITableView inside the UIScrollView for horizontal scrolling does not work as expected

I use a table view which has got the cells with varied set of information and which can not be contained with in the frame of the tableView. So I do need to have a horizontal scrolling capacity in the table view.
Since horizontal scrolling is not possible with tableview,I planned to use a scrollView with horizontal scroll. I added the tableView on top of the scrollView.
The problem I face is irrespective of the content size property of the scrollview, the scrollview never scrolls beyond the contentOffset value X of 256-320 pixels.
I am planning to achieve the effect as it is in the below screen shot
Try two things,
First Set the TableView height as total numberOfRows :
tableView.frame.size.y = numberOfRows * 44;
now disable the tableView Scrolling
and set he scrollView contentSize as per your need;
scollerView.contentSize = numberOfRowsintableView
Surely it will solve your problem
Set proper ContentSize for ScrollView in ViewDidLoad.
scollerView.contentSize = CGSizeMake(Width,Height);
Calculate the Width as Per Requirement And Height (you are using Tableview So You can take Height same as View Height)
Then it will Surely Scroll.
I implemented the entire functionality using code without using interface builder. It works as expected now. I did not know why it did not work when used with interface builder.

UICollectionView scrolling in both directions

I made a UICollectionView with a vertical scroll.
The width of the cell is more than than the screen width, so I created a customFlowLayout based on UICollectionViewFlow layout returning the right calculated content size.
However, this doesn't work. When the width of the cell is less than the screen width it works. Does it mean that we can't have width more than than screen width in vertical scroll?
It is the same for horizontal scroll, but then the height of the CollectionView is limited to screen height.
Is there any way to make it work?
As others have already said, the UICollectionView can only scroll one direction using a flow layout. However you can accomplish this very easily without creating a custom layout or using a third party library.
When you lay your view out in story board, you can put your UICollectionView embedded in a UIScrollView. Have the scrollview set up to scroll horizontally and the UICollectionView to scroll Vertically. Then set the UICollectionView.delaysContentTouchesto true so touches will pass through to the UIScrollView and not think you are trying to scroll the collectionview.
When you set up the UICollectionView, set it's size and the size of the cells to be what you actually want them to be (Wider than the actual screen) and lay them out accordingly.
Now in the containing UIViewController put this code in the view lifecycle
- (void)viewDidLayoutSubviews {
self.myScrollView.contentSize = self.myCollectionView.frame.size;
}
That's literally all you have to do to accomplish what you are describing. Now your scrollview should allow you to scroll horizontally to view your entire cell and your collectionView should scroll vertically through your cells.
Happy programming.
I'm not sure I've understood your problem.
But if you have made a custom layout, make sure you have implemented :
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
and that your layout attributes frame and size are set with correct values for your "large cell" index path.
Also make sure you have implemented :
- (CGSize) collectionViewContentSize;
This method returns the contentSize of the collection View. If contentSize.width > youAppFrame.width you should have horizontal scrolling. Same for height and vertical scrolling.
Also make sure your collectionView allows scrolling and that your layout is prepared correctly using :
- (void)prepareLayout
By the way, for your layout have you overloaded UICollectionViewLayout or UICollectionViewFlowLayout ?
Before you can do that you MUST use a different type of layout. The flow layout represents its items as a list and it spans these items in cells based on the available width.
If you want to have both horizontal and vertical scrolling you need to somehow specify the number of columns for your grid. the FlowLayout doesn't have that. A simple sollution is to make a subclass of UICollectionViewLayout and override collectionViewContentSize to make it retun a width = to the added sum of the cells widths of one row (this is where knowing how many collumns you want is necessary), plus any additional spacing between them. This will work fine if your cells have the same size per column, similar to a grid.
You should embed a UITableView into a UIScrollView.
ScrollView and TableView will have the same height but different widths.
This way UITableView will scroll vertical and UIScrollView will scroll horizontal.
Xcode 11+, Swift 5.
I solved my issue, I prepared video and code

UITableViewCell - How to handle dynamic sized content views from Nibs

When I want to have a custom cell, I generally add a UIView subclass to the cell's content view. For the layout of my subviews I use a nib. Then I wire up the nib to my UIView subclass. My issue is how to dynamically size content. Say my view has a lot UILabels inside it. I use layoutSubviews to position all the subviews - but it is only until that is done that I truly know the height of my cell. So currently in tableView:heightForRowAtIndexPath I setup my subview and call layoutIfNeeded so everything is positioned properly. Now I know the height of my cell and return it in the tableView:heightForRowAtIndexPath method. But now when tableView:cellForRowAtIndexPath is called the cell that I am given has a height of 44.0. When I added my subview to it - my subview is outside of its parent's bounds. Then when the cell is later resized in iOS to the height that I said I needed, my content is thrown off because of my autoresizingMask. Just trying to figure out if this is an issue others deal with or if I'm approaching it completely wrong. It just seems backwards that we ask for the height, then create a cell that is not that height.
Unfortunately, this is how UITableViews work: You need to provide the heights before the UITableViewCells are actually rendered.
And yes, everyone has to deal with it. :)
You could create an NSArray, add all your custom contentViews, set their frame according to the expected contentView bounds and then use this array as data source in tableView:heightForRowAtIndexPath: and tableView:cellForRowAtIndexPath:. While this isn't exactly efficient, it works fine for small data sets.
Also, here's a nice tutorial with this topic:
UITableViewCell Dynamic Height (by Matt Long)
A similar question on SO:
How can I do variable height table cells on the iPhone properly?

Resources