I have a table view and collection view to display image. Table view for vertical scroll and collection view for horizontal scroll. The image is displayed as full screen for the device. But when I scroll vertically half of previous cell is displayed and half of next cell is displayed. I used Table view constant is 0 to superview on all 4 constraints.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return myTableView.frame.size.height;
}
To return the height of the cell but even this is causing same issue.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.myTableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
return cell
}
This table view cell contains collection view
class TableViewCell: UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
func setUpCollectionView(){
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
collectionView = UICollectionView(frame: .zero,collectionViewLayout: layout)
collectionView?.register(VideoCollectionViewCell.self, forCellWithReuseIdentifier: VideoCollectionViewCell.identifier)
collectionView?.isPagingEnabled = true
collectionView?.dataSource = self
collectionView?.delegate = self
self.contentView.addSubview(collectionView!)
collectionView?.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
collectionView!.topAnchor.constraint(equalTo: contentView.topAnchor),
collectionView!.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
collectionView!.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
collectionView!.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
])
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.frame.width, height: self.frame.height)
}
}
This is my implementation, I don't want images to be displayed on half/half portion. I am trying to show it on full screen. Can anyone tell me why this is happening?
you need only UICollectionView display list images and set property scroll horizontal in UICollectionViewFlowLayout
myCollectionView.dataSource = self
myCollectionView.delegate = self
myCollectionView.contentMode = .scaleAspectFill
// scroll the images page by page, set property isPagingEnabled is true
myCollectionView.isPagingEnabled = true
let layout = UICollectionViewFlowLayout()
// set sroll horizontal here
layout.scrollDirection = .horizontal
myCollectionView.collectionViewLayout = layout
Related
I have been trying to fill in a UIImageView with a UIImage (car system image). I have tried numerous solutions online but can not seem to have it fill the UICollectionViewCell, awkward spacing seen here:
I figured since the UIView is the size of the UICollectionViewCell as seen here:
It must be the image is not scaling to the view. So I modified the content mode to scale to fill of the image view when creating the cells for the collection view, then adding this image view into the collection view cell:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CarCell", for: indexPath)
let carImageView = UIImageView(image: UIImage(systemName: "car"))
carImageView.contentMode = .scaleToFill
cell.addSubview(carImageView)
return cell
}
This doesn't seem to have any effect (even when using .bottom for the content mode the image does not move), but looking in the view hierarchy it seems this is what should be fixing it.
Does anyone know what I may be doing wrong?
Here is the storyboard:
Update:
I have added constraints to the image view with this code:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CarCell", for: indexPath)
let carImage = UIImage(systemName: "car")
let carImageView = UIImageView(image: carImage)
carImageView.contentMode = .scaleToFill
cell.addSubview(carImageView)
carImageView.topAnchor.constraint(equalTo: cell.topAnchor).isActive = true
carImageView.bottomAnchor.constraint(equalTo: cell.bottomAnchor).isActive = true
carImageView.leftAnchor.constraint(equalTo: cell.leftAnchor).isActive = true
carImageView.rightAnchor.constraint(equalTo: cell.rightAnchor).isActive = true
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let columns: CGFloat = 2
let collectionViewWidth = collectionView.bounds.width
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let spaceBetweenCells = flowLayout.minimumInteritemSpacing * (columns - 1)
let adjustedWidth = collectionViewWidth - spaceBetweenCells
let width: CGFloat = floor(adjustedWidth / columns)
let height: CGFloat = width
return CGSize(width: width, height: height)
}
But it ends up shrinking the image view rather than growing it to the size of the cell:
Give constraint to your imageView is zero from all side of collectionView cell and set image content mode to .scaleToFill and than show the result.
Thanks
I got you there. As I previously commented to show how you are giving constraints to image view, thus the error was there. There is a property called "translatesautoresizingmaskintoconstraints" which you need set while giving constraints to your views. You can read about it here.
Now, in your cellForItemAt you need to change:-
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CarCell", for: indexPath)
let carImage = UIImage(systemName: "car")
let carImageView = UIImageView(image: carImage)
carImageView.contentMode = .scaleToFill
carImageView.translatesautoresizingmaskintoconstraints = false
cell.addSubview(carImageView)
carImageView.centerXAnchor.constraint(equalTo: cell.contentView.centerXAnchor).isActive = true
carImageView.centerYAnchor.constraint(equalTo: cell.contentView.centerYAnchor).isActive = true
carImageView.heightAnchor.constraint(equalTo: cell.contentView.heightAnchor).isActive = true
carImageView.widthAnchor.constraint(equalTo: cell.contentView.widthAnchor).isActive = true
return cell
}
As you can notice I've also changed the constraint to give an idea about how you should give the constraints if you want to set the image size as exact as your cell. You should always access cell's content view when you're giving constraint not the cell.
I am trying to create a collection view that has a header cell (dynamically sized) and some "normal" content cells (also dynamically sized). Therefore, the collection view is initialized as follows:
private lazy var timelineCollectionView: UICollectionView = {
let flowLayout = UICollectionViewFlowLayout()
flowLayout.scrollDirection = .vertical
flowLayout.sectionInset = UIEdgeInsets(top: self.coloredTitleBarHeight, left: 0, bottom: 0, right: 0) // assume that coloredTitlebarHeight is a constant of 120
flowLayout.estimatedItemSize = CGSize(width: self.view.frame.width, height: 10)
flowLayout.minimumInteritemSpacing = 0
flowLayout.minimumLineSpacing = 0
let cv = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
cv.alwaysBounceVertical = true
cv.contentInsetAdjustmentBehavior = .never
cv.backgroundColor = .clear
cv.scrollIndicatorInsets = UIEdgeInsets(top: self.coloredTitleBarHeight - self.getStatusBarHeight(), left: 0, bottom: 0, right: 0)
cv.delegate = self
cv.dataSource = self
cv.register(TLContentCell.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "content-header-cell")
cv.register(TLContentCell.self, forCellWithReuseIdentifier: "comment-cell")
return cv
}()
The collectionView is part of a ViewController that conforms to the following protocols: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
Then, I use the following code to create a header cell:
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let cell = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "content-header-cell", for: indexPath) as! TLContentCell
cell.timelineContent = tlContentItem
cell.delegate = self
return cell
}
Last but not least, the dequeuing of the regular cells:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "comment-cell", for: indexPath)
return cell
}
Output:
The collectionView displays the header cell as well as the item cells, however, the section Insets are not applied.
I would be very happy if you could provide me with any suggestion regarding this strange behavior.
Section insets are applied to contents only in UICollectionViewFlowLayout.
Using Section Insets to Tweak the Margins of Your Content
Section insets are a way to adjust the space available for laying out cells.
You can use insets to insert space after a section’s header view and
before its footer view. You can also use insets to insert space around
the sides of the content. Figure 3-5 demonstrates how insets affect
some content in a vertically scrolling flow layout. source
Is there a way to allow paging in a UIScrollView but restrict the paging to one direction.
For example: Allowing the user to page background (to the left) but not forward. Use case being for some type of onboarding. I know I can add buttons that move forward, have them enabled or disabled, and remove swiping but I rather not.
I don't know if I have well understand what you want but what about using a UICollectionView:
lazy var onBoardingCollectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
let cv = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
cv.showsHorizontalScrollIndicator = false
cv.showsVerticalScrollIndicator = false
cv.isPagingEnabled = true
return cv
}()
You add you custom cell with the size of the screen as well by the method in UICollectionViewDelegateFlowLayout:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: SCREENW, height: SCREENH)
}
if you don't want to go in a specific direction you can try get the current cell displaying and removing the previous one of the dataSource and collection with this method.
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let currentPage = Int(scrollView.contentOffset.x / scrollView.frame.width)
print("current cell: ", currentPage)
}
I am using Swift to build an iOS application for the Hospital I work at.
Somehow, in a specific feature I have to put a UICollectionView inside the UICollectionViewCell. The one I want to achieve was for every content of the parent UICollectionView (vertical scrolling) would have several children (Which can be scrolled horizontal) depending on the parent row.
For illustration, I have to display list of doctors (name & photo) and then I have to display each of the practice schedule of them below their name and photo. The practice schedule would vary depending on each doctor. So, I have to put it inside the UICollectionView.
I have tried several solutions that I found on the web, but I still cannot approach it.
The most problem that I can't solve was: I don't know where is the place in the code to load the child data source (doctor schedule) and when I could load it, because I can't have two functions like below:
collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
this is the one I want to achieve
the UIImage and doctor name (UILabel) was in the parent UICollectionViewCell (scroll vertically), and then everything in the box (practice day n practice time) are the child UICollectionView (scroll horizontally)
PS: there are many doctors, and each of the doctor has several practice day.
please help me how to do this
If you really want to insert an collectionView inside a collectionViewCell then there is a pretty simple step. Create an instance of UICollectionView and add it the collectionViewCell. You can use this example if you like.
//
// ViewController.swift
// StackOverFlowAnswer
//
// Created by BIKRAM BHANDARI on 18/6/17.
// Copyright © 2017 BIKRAM BHANDARI. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
let cellId = "CellId"; //Unique cell id
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red; //just to test
collectionView.register(Cell.self, forCellWithReuseIdentifier: cellId) //register collection view cell class
setupViews(); //setup all views
}
func setupViews() {
view.addSubview(collectionView); // add collection view to view controller
collectionView.delegate = self; // set delegate
collectionView.dataSource = self; //set data source
collectionView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true; //set the location of collection view
collectionView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true; // top anchor of collection view
collectionView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true; // height
collectionView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true; // width
}
let collectionView: UICollectionView = { // collection view to be added to view controller
let cv = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()); //zero size with flow layout
cv.translatesAutoresizingMaskIntoConstraints = false; //set it to false so that we can suppy constraints
cv.backgroundColor = .yellow; // test
return cv;
}();
//deque cell
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath);
// cell.backgroundColor = .blue;
return cell;
}
// number of rows
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5;
}
//size of each CollecionViewCell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 200);
}
}
// first UICollectionViewCell
class Cell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
let cellId = "CellId"; // same as above unique id
override init(frame: CGRect) {
super.init(frame: frame);
setupViews();
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId); //register custom UICollectionViewCell class.
// Here I am not using any custom class
}
func setupViews(){
addSubview(collectionView);
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true;
collectionView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true;
collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true;
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true;
}
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout();
layout.scrollDirection = .horizontal; //set scroll direction to horizontal
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout);
cv.backgroundColor = .blue; //testing
cv.translatesAutoresizingMaskIntoConstraints = false;
return cv;
}();
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath);
cell.backgroundColor = .red;
return cell;
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5;
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.frame.width, height: self.frame.height - 10);
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
This might be a little late, but for people out here still trying to find an answer.
After some research and digging, I stumbled upon several posts stating reasons why you should NOT have your cell be the delegate for you collectionView. So, I was lost because pretty much all solutions I had found were doing this, until I finally found what I believe is the best way to have nested collectionViews.
To give some background, my app included not only one but 2 collectionViews inside different cells of another collectionView, so setting the delegates with tags and all that, wasn't really the best approach nor the correct OO solution.
So the best way to do it is the following:
First you have to created a different class to serve as your delegate for the inner collectionView. I did it as such:
class InnerCollectionViewDelegate: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
// CollectionView and layout delegate methods here
// sizeForItemAt, cellForItemAt, etc...
}
Now, in your inner collectionView (or rather the cell where you have the inner collectionView) create a function that will allow you to set its delegates
class InnerCell: UICollectionViewCell {
var collectionView: UICollectionView
init() {
let layout = UICollectionViewFlowLayout()
collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height), collectionViewLayout: layout)
}
func setCollectionViewDataSourceDelegate(dataSourceDelegate: UICollectionViewDataSource & UICollectionViewDelegate) {
collectionView.delegate = dataSourceDelegate
collectionView.dataSource = dataSourceDelegate
collectionView.reloadData()
}
}
And lastly, in your ViewController where you have your outermost (main) collectionView do the following:
First instantiate the delegate for the inner collectionView
var innerDelegate = InnerCollectionViewDelegate()
and then
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
if let cell = cell as? InnerCell {
cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: innerDelegate)
}
}
This might not be perfect, but at least you have separation of concerns, as your cell should NOT be the delegate. Remember your cell should only be responsible for displaying info, not trying to figure out what the size of the collectionView should be, etc.
I did find similar answers that dealt with setting the collectionViews tag and whatnot, but I found that that made it way harder to deal with each collectionView individually, plus dealing with tags can't result in spaghetti code or unintended behaviours.
I left out registering and dequeuing the cell, but I'm sure you're all familiar with that. If not, just let me know and I'll try to walk you through it.
There are multiple ways to tackle the problem of a horizontal collection inside another a vertical list collection.
The simplest would be to make the ViewController you are presenting the main UICollectionView to the dataSouce and delegate for both collection views. You can set the collection view inside the cell also to be served from here.
This article about placing collection view inside a table view explains the problem in a much elaborate way and the code for the same can be found here.
Add collectionView in collection view cell , and add delagate methods in collectionviewclass.swift. Then pass list you want to show in cell in collectionview's cellforrowatindexpath. If you didn't success on implimenting it then let me know . i will provide you code as i have already implemented it in that way.
I am trying to make home screen on my ios 10 app like on photo from above. Green view is actually scroll view and i set constraints for it to cover whole View. Everything on scrollView i want to make scrollable. Yellow part is collection view with prototype cell. Number of items on this view is 6. Cell consists of photo and title. Table view is list of news (photo + title). When start app in table view I load 10 last news and rest of the news I getting with "load more" mechanism. I need proper work of app even on landscape orientation. I have problem to define this layout because collection view and tableView have dynamic height and space between them must be fixed. Usually on almost all tutorials people just fixed scrollView and GridView and in that case app looks good on portrait orientation but i need a more flexibility. Is it possible to achieve this through auto layout and constraints and if yes what are correct directions
UPDATE:
Content view
Collection view
What I want to achieve is to make collection view as a two columns and 3 rows in portrait orientation and 3 columns and 2 rows on landscape. Currently I have collectionView with a scroll but I want to be expanded al the time because content of collectionView should consists of 6 highlighted news.
On viewDidLoad I tried to set table view on correct position (after collection view):
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
collection.dataSource = self
collection.delegate = self
tableView.delegate = self
tableView.dataSource = self
self.view.addConstraint(
NSLayoutConstraint(
item: tableView,
attribute: .top,
relatedBy: .equal,
toItem: collection,
attribute: .bottom,
multiplier: 1.0,
constant: 20
))
tableView.frame = CGRect(x: 0,y: collection.collectionViewLayout.collectionViewContentSize.height,width: tableView.frame.width,height: tableView.frame.width ); // set new position exactly
downloadArticles(offset: "0") {}
}
An example of what I want to achieve is:
Currently I have this:
I think I got it working like this:
import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UITableViewDataSource, UICollectionViewDelegateFlowLayout, UITableViewDelegate {
#IBOutlet var collectionView: UICollectionView!
#IBOutlet var tableView: UITableView!
#IBOutlet var collectionViewHeightConstraint: NSLayoutConstraint!
#IBOutlet var tableViewHeightConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "gridCell")
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "listCell")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// shrink wrap the collectionView and tableView to fit their content height snuggly
self.collectionViewHeightConstraint.constant = self.collectionView.contentSize.height
self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - CollectionView Methods -
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 6;
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
cell.backgroundColor = UIColor.lightGray
}
func calculateGridCellSize() -> CGSize {
// -----------------------------------------------------
// Calculate the size of the grid cells
// -----------------------------------------------------
let screenWidth = self.view.frame.size.width
let screenHeight = self.view.frame.size.height
var width:CGFloat = 0
var height:CGFloat = 0
if(UIDeviceOrientationIsPortrait(UIDevice.current.orientation)) {
width = screenWidth / 2.0 - 0.5
height = width
}
else {
width = screenWidth / 3.0 - 1.0
height = screenHeight / 2.0 - 0.5
}
let size:CGSize = CGSize(width: width, height: height)
return size
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return self.calculateGridCellSize()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { (context) in
print("New screen size = \(size.width) x \(size.height)")
self.collectionView.collectionViewLayout.invalidateLayout()
self.collectionViewHeightConstraint.constant = self.collectionView.contentSize.height
self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
self.view.layoutIfNeeded()
}) { (context) in
self.collectionViewHeightConstraint.constant = self.collectionView.contentSize.height
self.tableViewHeightConstraint.constant = self.tableView.contentSize.height
self.view.layoutIfNeeded()
}
}
// MARK: - TableView Methods -
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "listCell", for: indexPath)
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.textLabel?.text = "list cell \(indexPath.row)"
}
}
For the interface layout, I did this:
Add scrollView to main view
Pin scrollview all four sides main view
Add contentView to scrollView
Pin contentView all four sides to scrollView
Make contentView width equal to scrollView width
Add collectionView to contentView
Add tableView to contentView and vertically below collectionView
Pin left, top, right of collectionView to contentView
Pin left, bottom, right of tableView to contentView and top of tableView to bottom of collectionView
Make collectionView height 667 and create IBOutlet NSLayoutConstraint for collectionView height (so we can update it later)
Make tableView height 667 and create IBOutlet NSLayoutConstraint for tableView height (also to update later)
Make collectionView min item spacing 1 and line spacing 1
Disable scrollingEnabled for collectionView
Disable scrollingEnabled for tableView
Connect collectionView datasource and delegate to controller
Connect tableView datasource and delegate to controller
Here's a screenshot of the layout if it's any help.
Usually I build my UI using pure code and you would be able to copy and paste, hit the run button but since you're using using Storyboard, I showed it using Storyboard, hopefully you can follow my layout setup instructions.
Here's the result:
Is that what you wanted?