I tried lots of answer from stack overflow. But I did not get relevant answer for iOS 11. As you can notice I got space at top in UICollectionview. Please help me to fix this issue.
ScreenShort :
What I tried :
1) self.automaticallyAdjustsScrollViewInsets = false
This one is deprecated in iOS 11
2) Uncheck "Adjust Scroll View insets"
3) This link
automaticallyAdjustsScrollViewInsets is deprecated in iOS 11. Try to set contentInsetAdjustmentBehavior for iOS 11.
if #available(iOS 11.0, *) {
collectionView.contentInsetAdjustmentBehavior = .never
} else {
self.automaticallyAdjustsScrollViewInsets = false
}
Try adding edgesForExtendedLayout = [] in your viewDidLoad
as well as;
if #available(iOS 11.0, *) {
collectionView.contentInsetAdjustmentBehavior = .never
} else {
self.automaticallyAdjustsScrollViewInsets = false
}
I had the same problem in Xcode 11. And here is my solution:
Okay so :
The spacing issue could be mostly in part because you have the collectionView inside the UIView. Which by the way you should only use 1 collection view and you only need 1 view controller.
1.
Just put the collection view inside the first VC and replace the UIView with the collectionView.
2.
Then just drag another prototype reusable cell into the collection view. You can have multiple custom cells in one collection view in storyboard! Make cell 1 your first custom collection view cell type and cell 2 your second. When the segment bar switches just use a function to change the data the collectionView will present when you reload the collectionView, you can change the type of cell and array the collection view will present in the UICollectionViewDatasource methods.
Something along these lines:
enum MediaTypes {
case pictures
case videos
}
fileprivate var arrayToPresent: MediaTypes = .pictures
...
func segmentChanged(){
switch self.segmentController.selectedIndex {
case 1:
self.arrayToPresent = .videos
default:
self.arrayToPresent = .pictures
}
//Logic to reload Collection View
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch self.arrayToPresent {
case .pictures:
let cell = collectionView.deq... as! PictureCollectionViewCell
return cell
case .videos:
let cell = collectionView.deq... as! VideoCollectionViewCell
return cell
}
}
Related
I'm working on a legacy app and trying to embed a swiftUI view inside a UIKit UITableView. The SwiftUI view is a LazyHGrid with a number of items based on a user's number of accounts. The idea is to display the first 1-3 items (if there are any), and a "More" button, which, when tapped, displays the rest of the items.
The SwiftUI piece is working correctly, and initially the tableView displays it correctly, like so:
three tiles working correctly. However, when I tap the "More" button, the other items pop in, but the row height in the table doesn't adjust, so they just overlap the other content in the table, like so: tiles overlapping other content.
Here's the host function that controls the swiftUI view:
func host(_ view: Content, parent: UIViewController) {
hostingController.rootView = view
hostingController.view.invalidateIntrinsicContentSize()
let requiresControllerMove = hostingController.parent != parent
if requiresControllerMove {
// remove old parent if exists
removeHostingControllerFromParent()
parent.addChild(hostingController)
}
if !contentView.subviews.contains(hostingController.view) {
contentView.addSubview(hostingController.view)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
hostingController.view.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
hostingController.view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
hostingController.view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
hostingController.view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
}
if requiresControllerMove {
hostingController.didMove(toParent: parent)
}
}
I register the cell in the viewDidLoad in the UIKit controller:
self.tableView.register(SwiftUIHostTableViewCell<BillingTileGridView>.self, forCellReuseIdentifier: "BillingTileGridViewCell")
(This code was already present in the viewDidLoad):
self.tableView.estimatedRowHeight = 60
self.tableView.rowHeight = UITableView.automaticDimension
And then I create the cell like so in the tableView cellForRowAt function:
if let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseID, for: indexPath) as? SwiftUIHostTableViewCell<BillingTileGridView> {
let view = BillingTileGridView(viewModel: BillingTileGridViewModel(), adjustHeight: {
})
cell.host(view, parent: self)
return cell
}
I tried using a callback to re-load the table height for the button action, like this:
let view = BillingTileGridView(viewModel: BillingTileGridViewModel(), adjustHeight: {
tableView.beginUpdates()
tableView.endUpdates()
})
like I'd seen in questions like this one, Swift: How to reload row height in UITableViewCell without reloading data, but it didn't seem to do anything. Do I just need to calculate the height manually based on how many rows I have, and set the height explicitly to that?
I have recently migrated some code to new iOS 11 beta 5 SDK.
I now get a very confusing behaviour from UITableView. The tableview itself is not that fancy. I have custom cells but in most part it is just for their height.
When I push my view controller with tableview I get an additional animation where cells "scroll up" (or possibly the whole tableview frame is changed) and down along push/pop navigation animation. Please see gif:
I manually create tableview in loadView method and setup auto layout constraints to be equal to leading, trailing, top, bottom of tableview's superview. The superview is root view of view controller.
View controller pushing code is very much standard: self.navigationController?.pushViewController(notifVC, animated: true)
The same code provides normal behaviour on iOS 10.
Could you please point me into direction of what is wrong?
EDIT: I have made a very simple tableview controller and I can reproduce the same behavior there. Code:
class VerySimpleTableViewController : UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = String(indexPath.row)
cell.accessoryType = .disclosureIndicator
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let vc = VerySimpleTableViewController.init(style: .grouped)
self.navigationController?.pushViewController(vc, animated: true)
}
}
EDIT 2: I was able to narrow issue down to my customisation of UINavigationBar. I have a customisation like this:
rootNavController.navigationBar.setBackgroundImage(createFilledImage(withColor: .white, size: 1), for: .default)
where createFilledImage creates square image with given size and color.
If I comment out this line I get back normal behaviour.
I would appreciate any thoughts on this matter.
This is due to UIScrollView's (UITableView is a subclass of UIScrollview) new contentInsetAdjustmentBehavior property, which is set to .automatic by default.
You can override this behavior with the following snippet in the viewDidLoad of any affected controllers:
tableView.contentInsetAdjustmentBehavior = .never
https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior
In addition to maggy's answer
OBJECTIVE-C
if (#available(iOS 11.0, *)) {
scrollViewForView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
This issue was caused by a bug in iOS 11 where the safeAreaInsets of
the view controller's view were set incorrectly during the navigation
transition, which should be fixed in iOS 11.2. Setting the
contentInsetAdjustmentBehavior to .never isn't a great workaround
because it will likely have other undesirable side effects. If you do
use a workaround you should make sure to remove it for iOS versions >=
11.2
-mentioned by smileyborg (Software Engineer at Apple)
You can edit this behavior at once throughout the application by using NSProxy in for example didFinishLaunchingWithOptions:
if (#available(iOS 11.0, *)) {
[UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
Here's how I managed to fix this issue while still allowing iOS 11 to set insets automatically. I am using UITableViewController.
Select "Extend edges under top bars" and "Extend edges under opaque bars" in your view controller in storyboard (or programmatically). The safe area insets will prevent your view from going under the top bar.
Check the "Insets to Safe Area" button on your table view in your storyboard. (or tableView.insetsContentViewsToSafeArea = true) - This might not be necessary but it's what I did.
Set the content inset adjustment behavior to "Scrollable Axes" (or tableView.contentInsetAdjustmentBehavior = .scrollableAxes) - .always might also work but I did not test.
One other thing to try if all else fails:
Override viewSafeAreaInsetsDidChange UIViewController method to get the table view to force set the scroll view insets to the safe area insets. This is in conjunction with the 'Never' setting in Maggy's answer.
- (void)viewSafeAreaInsetsDidChange {
[super viewSafeAreaInsetsDidChange];
self.tableView.contentInset = self.view.safeAreaInsets;
}
Note: self.tableView and self.view should be the same thing for UITableViewController
This seems more like a bug than intended behavior. It happens when navigation bar is not translucent or when background image is set.
If you just set contentInsetAdjustmentBehavior to .never, content insets won't be set correctly on iPhone X, e.g. content would go into bottom area, under the scrollbars.
It is necessary to do two things:
1. prevent scrollView animating up on push/pop
2. retain .automatic behaviour because it is needed for iPhone X. Without this e.g. in portrait, content will go below bottom scrollbar.
New simple solution: in XIB: Just add new UIView on top of your main view with top, leading and trailing to superview and height set to 0. You don't have to connect it to other subviews or anything.
Old solution:
Note: If you are using UIScrollView in landscape mode, it still doesn't set horizontal insets correctly(another bug?), so you must pin scrollView's leading/trailing to safeAreaInsets in IB.
Note 2: Solution below also has problem that if tableView is scrolled to the bottom, and you push controller and pop back, it will not be at the bottom anymore.
override func viewDidLoad()
{
super.viewDidLoad()
// This parts gets rid of animation when pushing
if #available(iOS 11, *)
{
self.tableView.contentInsetAdjustmentBehavior = .never
}
}
override func viewDidDisappear(_ animated: Bool)
{
super.viewDidDisappear(animated)
// This parts gets rid of animation when popping
if #available(iOS 11, *)
{
self.tableView.contentInsetAdjustmentBehavior = .never
}
}
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
// This parts sets correct behaviour(insets are correct on iPhone X)
if #available(iOS 11, *)
{
self.tableView.contentInsetAdjustmentBehavior = .automatic
}
}
I can reproduce the bug for iOS 11.1 but it seems that the bug is fixed since iOS 11.2.
See http://openradar.appspot.com/34465226
please make sure along with above code, add additional code as follows. It solved the problem
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) // print(thisUISBTV.adjustedContentInset)
}
Also if you use tab bar, bottom content inset of the collection view will be zero. For this, put below code in viewDidAppear:
if #available(iOS 11, *) {
tableView.contentInset = self.collectionView.safeAreaInsets
}
In my case this worked (put it in viewDidLoad):
self.navigationController.navigationBar.translucent = YES;
Removing extra space at top of collectionView or tableView
if #available(iOS 11.0, *) {
collectionView.contentInsetAdjustmentBehavior = .never
//tableView.contentInsetAdjustmentBehavior = .never
} else {
automaticallyAdjustsScrollViewInsets = false
}
Above code collectionView or tableView goes under navigation bar.
Below code prevent the collection view to go under the navigation
self.edgesForExtendedLayout = UIRectEdge.bottom
but I love to use below logic and code for the UICollectionView
Edge inset values are applied to a rectangle to shrink or expand the
area represented by that rectangle. Typically, edge insets are used
during view layout to modify the view’s frame. Positive values cause
the frame to be inset (or shrunk) by the specified amount. Negative
values cause the frame to be outset (or expanded) by the specified
amount.
collectionView.contentInset = UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
//tableView.contentInset = UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
The best way for UICollectionView
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: -30, left: 0, bottom: 0, right: 0)
}
Delete this code work for me
self.edgesForExtendedLayout = UIRectEdgeNone
if #available(iOS 11, *) {
self.edgesForExtendedLayout = UIRectEdge.bottom
}
I was using UISearchController with custom resultsControllers that has table view. Pushing new controller on results controller caused tableview to go under search.
The code listed above totally fixed the problem
I have an UITableView which consists of prototype cells. I want to put an UIButton inside the bottom of the UITableView using Interface Builder.
I added the UIButton in the footer of the UITableView:
I added a purple background for the Footer View and a green background colour for the UITableView. In the picture above it shows the Button at the bottom of the footer. However this isn't equal to the bottom of the UITableView.
The GIF below displays that the button is placed bellow the cells but not inside the bottom of the UITableView. I want it to appear at the bottom in the UITableView. Not under the UITableView. The following GIF displays this problem:
My question is: How do I set an UIButton inside an UITableView at the bottom of the UITableView using Interface Builder?
This is what I want to achieve (From Apple's ResearchKit):
Edit: The UIButton should be inside the UITableView. Suggestions where the UIButton is placed outside the TableView and pinned underneath don't achieve my goal.
You are setting footer width wrong.Set it fixed height so that button sticks to that particular height(Should be Fixed like 60px)
Check Demo Code for Storyboard structure and constraints
So I had to slightly swizzle it, but got it working by doing the below things:
Pull the UIButton out to the same level in the view heirarcy as
the tableview.
Embed the tableview and the button inside a view
Embed the above view inside another view
Pin edges of view #3 (Pinned View) to superview
Pin top, left & right edges of view #2 (Resizing View) to view #3 edges. And set a constraint of equal height to view #3.
Set an outlet in the view controller for the equal height constraint
The view heirarcy in IB should look like this:
Now in the view controller code, you need to do the following things:
Create instance var for the keyboard offset value
var keyboardOffset: CGFloat = 0
set notifications and observers for the keyboard willShow and
willHide
notificationCenter.addObserver(self, selector: #selector(keyboardWillShow(_:)), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
notificationCenter.addObserver(self, selector: #selector(keyboardWillHide(_:)), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
In keyboardWillShow, cache the keyboard height value.
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
keyboardOffset = keyboardSize.height
}
Create didSet method on the keyboardOffset var, and animate the height of the view by that value each time it is set
var keyboardOffset: CGFloat = 0 {
didSet {
resizingViewHeight.constant = -keyboardOffset
UIView.animate(withDuration: 0.2) {
self.view.layoutIfNeeded()
}
}
}
Make sure you set the offset back to 0 in keyboardWillHide
keyboardOffset = 0
Every time the keyboard now appears, the view that is containing the tableview will reduce in size and therefore pull the contents up with it, providing the shrinking tableview effect that you are hoepfully looking for!
Add a view that contains the UIButton to the bottom of the UIViewController where the UITableView is. Give it the constraints to attach to left, right and bottom side of super view and probably a fixed height.
Then attach the UITableView's bottom constraint to the top of the view that contains the UIButton.
You should get the effect you're looking for.
NOTE: For the button you can give centered Y and X in superview constraints to keep it centered.
Footer is apperead always after the last cell of your table view so your output is correct.
If you wanted the button bottom of tableview then add button below the tableview in hierarchy not as a footer. But it makes your button static that means it didn't matter how much cells you have, button is always button of the tableView but it is not a scrollable like as it is now.
I tried the accepted answer, but couldn't get it to work. I found that the footer view always stayed pinned to the bottom of the screen, regardless of the size of the TableView (just as if it were a sibling of the TableView). I ended up following an approach suggested here: https://stackoverflow.com/a/18047772/5778751 The basic idea is that you programmatically determine the height of the TableView and depending on the result, you EITHER display a footer internal to the TableView OR display a view which is a sibling of the TableView.
I have a perfect solution for this problem. Using default was never that meaningful in my life.
The button under the view is also a table view cell from another section but its configuration of header height and interior design is just different from the above cells.
So I have five different sections. The first three of them are standard table view cells(SettingTableViewCell) but the last two(cache and version) are custom buttons. In the header title, I init for those empty titles.
enum Section: Int {
case adjustSettings
case about
case agreements
case cache
case version
static var numberOfSections: Int { return 5 }
var reuseIdentifier: String { return "SettingTableCell" }
var headerTitle: String? {
switch self {
case .adjustSettings: return "settings.adjust.section.title".localized
case .about: return "settings.headertitle.about".localized
case .agreements: return "agreement.title".localized
case .cache: return ""
case .version: return ""
}
}
Then I configured with cell will be in which section with below code. Cache and version have only one cell which will be our buttons.
var cells: [CellType] {
switch self {
case .adjustSettings:return [.notification,.language ]
case .about: return [.rate, .contact, .invite]
case .agreements: return [.membership, .kvkk, .illuminate]
case .cache: return [.cache]
case .version: return [.version]
}
}
I have three different set functions inside my settingsTableViewCell.
For setting up standard table view cell -> .setDefault(text: text)
For setting up my clean cache button -> .setCache(text: text)
Last for shoving version info -> .setVersion(version: version)
with the above cellForRowAt, I am switching rows and setting them up accordingly. My default is .setDefault
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let section = Section(rawValue: indexPath.section) else {
assertionFailure()
return UITableViewCell()
}
let row = section.cells[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: section.reuseIdentifier) as! SettingTableCell
switch row {
case .version:
cell.setVersion(version: getVersion())
case .cache:
ImageCache.default.calculateDiskCacheSize(completion: { size in
if size == 0 {
cell.setCache(text: "settings.clear.data".localized)
} else {
let byte = Int64(size)
let fileSizeWithUnit = ByteCountFormatter.string(fromByteCount: byte, countStyle: .file)
cell.setCache(text: "settings.cler.data.with.string".localized + "(\(String(describing: fileSizeWithUnit)))")
}
})
default:
cell.setDefault(text: row.text)
}
return cell
}
You can adjust button heights as below by switching section.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let section = Section(rawValue: indexPath.section) else { return 0 }
switch section {
case .cache: return 44
case .version: return 44
default: return 56.0
}
You can adjust the gap between each button as below.
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
guard let section = Section(rawValue: section) else { return 0 }
switch section {
case .adjustSettings: return 46
case .about: return 46
case .agreements: return 46
case .cache: return 9
case .version: return 0.5
default: return 46
}
And finally, this is my cell where I set .set functions to customize each cell as I pleased.
class SettingTableCell: UITableViewCell {
#IBOutlet weak var line: UIView!
#IBOutlet weak var content: UIView!
#IBOutlet weak var arrowView: UIView!
#IBOutlet weak var labelSetting: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
func setVersion(version: String) {
arrowView.isHidden = true
line.isHidden = true
content.backgroundColor = .clear
labelSetting.label(textStr: version, textColor: KSColor.neutral400.getColor(), textFont: .sfProTextRegular(size: 13), fontSize: 13, lineSpacing: -0.13, paragraphStyle: NSMutableParagraphStyle())
labelSetting.textAlignment = .center
self.accessoryType = .none
}
func setCache(text: String) {
arrowView.isHidden = true
line.isHidden = true
content.backgroundColor = KSColor.neutral100.getColor()
labelSetting.label(textStr: text, textColor: KSColor.neutral700.getColor(), textFont: .sfProTextMedium(size: 14), fontSize: 14, lineSpacing: -0.14, paragraphStyle: NSMutableParagraphStyle())
labelSetting.textAlignment = .center
self.accessoryType = .none
}
func setDefault(text: String) {
labelSetting.label(textStr: text, textColor: KSColor.neutral700.getColor(), textFont: UIFont.sfProTextMedium(size: 16), fontSize: 16, lineSpacing: -0.16, paragraphStyle: NSMutableParagraphStyle())
}
}
And the outcome is I have 5 sections but the last two are buttons.
I have 5 tableViewControllers using UISearchResultsUpdating protocol with the new UISearchController
private var resultSearchController:UISearchController!
resultSearchController = UISearchController(searchResultsController: nil)
resultSearchController.searchResultsUpdater = self
resultSearchController.dimsBackgroundDuringPresentation = false
resultSearchController.searchBar.sizeToFit()
tableView.tableHeaderView = resultSearchController.searchBar
tableView.tableHeaderView?.backgroundColor = UIColor.redColor()
tableView.tableHeaderView?.userInteractionEnabled = true
When I load this viewController by pushing it on top of other viewControllers, everything works fine. I can touch the cells, I can touch the searchBar and operate a search.
Now, when I put 5 (or less, it doesn't matter) of those tableViewControllers inside a controller containing a scrollView
let rect: CGRect = self.view.frame
scrollView = UIScrollView(frame: rect)
scrollView.pagingEnabled = true
scrollView.addSubview(oneTableViewController)
scrollView.addSubview(twoTableViewController)...
I can navigate through the 5 tableViewController by swiping left and right.
I can select a row in any tableview.
but I can't touch the searchBar anymore...
I tried to set:
scrollView.exclusiveTouch = false
ensure that tableView.tableHeaderView?.userInteractionEnabled = true
Any ideas?
By looking at your problem I think there can be a better way to achieve what you are doing.
Instead of using 5 tableview in a scrollview, I will say use one tableview and you can set its cell to show data.. Now you can add scrollview in different cell and add your data on scrollview that will allow you to scroll left and right.
Otherwise if you wanna continue the same approach you are doing then,
you can rotate tableview to 90 degree so that it gives you a feel of left and right scrolling.
You can use your tableview'd delegate:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//do the check
if tableView == YourTableView {
//do your stuff. As you have indexPath you can get row at that indexPath
}
}
If you try to do such thing, don't forget to add the tableViewControllers as childViewControllers of your main ViewController.
self.addChildViewController(tableVC1)
tableVC1.didMoveToParentViewController(self)
self.addChildViewController(tableVC2)
tableVC2.didMoveToParentViewController(self)
now everything works fine!
I have a UICollectionView that holds a bunch of a photos.
However, if I scroll to the bottom the scrollview does not let me scroll to the bottom of the last few rows (it snaps back). I have tried override the collectionView.contentSize and just adding 1000 to the height but it doesn't fix the problem.
collectionView.contentSize = CGSizeMake(collectionView.contentSize.width, collectionView.contentSize.height + 1000)
Here is a video of the problem:
https://www.youtube.com/watch?v=fH57_pL0OjQ&list=UUIctdpq1Pzujc0u0ixMSeVw
Here is my code to create cells:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("selectPhotoCell", forIndexPath: indexPath) as B_SelectPhotoControllerViewCell
let reuseCount = ++cell.reuseCount
let asset = currentAssetAtIndex(indexPath.item)
PHImageManager.defaultManager().requestImageForAsset(asset, targetSize:_cellSize, contentMode: .AspectFit, options: nil)//the target size here can be set to CGZero for a super blurry preview
{
result, info in
if reuseCount == cell.reuseCount
{
cell.imageView.image = result
cell.imageView.frame = CGRectMake(0, 0,self._cellSize.width,self._cellSize.height)
}
}
return cell
}
private func currentAssetAtIndex(index:NSInteger)->PHAsset
{
if let fetchResult = _assetsFetchResults
{
return fetchResult[index] as PHAsset
}else
{
return _selectedAssets[index]
}
}
Update:
Because I am adding this as a child view controller, there seems to be some problems with the offsetting of the scrollview. I haven't fixed it yet but when open this view without adding it as a child view to another view controller, the scrollview is the correct size
The problem was I was adding this as a child view controller.
As a result, after doing some animations, the UICollectionView bounds were sizing to the view it was attached to. As a result its height was wrong and hence why it was getting cut off.
I just came across this question from a quick Google and felt I could add something useful.
I am running a segmentedControl with a UIView that changes to different UICollectionViews on the segment change and I couldn't get the collectionView to scroll fully down.
This may not be the solution for all, but I found that if I went to the XIB I was loading in the view and set size to freeform and decrease it by the size of a cell I had removed the problem.
suspect your CollectionView's bottomAchor was not set correctly to the parent uiview's safeAreaLayoutGuide bottomAnchor