How to show a parent view which is outside tableview and is scrollable?










0















I have a scenario where I need to show a parent view with shadow and corner radius containing a long list of reusable items. I used a tableView to display items. But I stuck at making my tableview expand as much as its contentSize. It works but not accurate. Any solutions?



Edit:



Desired result:
enter image description here



I used the following reference for self sizing tableview.
Self Sizing UITableView



I made a few modifications as below:



final class SelfSizedTableView: UITableView 

var maxHeight = CGFloat.greatestFiniteMagnitude

override func reloadData()
super.reloadData()
self.invalidateIntrinsicContentSize()
self.layoutIfNeeded()


override var intrinsicContentSize: CGSize
let height = min(contentSize.height, maxHeight)
let size = CGSize(width: contentSize.width, height: height)
return size





I used a parent tableView with a cell having my containerView and embedding this self sized tableView.



class MyContainerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var parentTableView: UITableView!

// MARK: - Life Cycle
override func viewDidLoad()
super.viewDidLoad()
setupViews()


private func estimateDataHeight() -> CGFloat
let detailCellHeight: CGFloat = 32
let headingCellHeight: CGFloat = 43
let headings: CGFloat = headingCellHeight*2
let detailsHeight: CGFloat = detailCellHeight*4
let baseHeight = headings + detailsHeight
let membersHeight =
CGFloat(sectionsArray.count) * detailCellHeight
return baseHeight + membersHeight



// MARK: - UITableViewDataSource
extension MyContainerViewController

func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
return 1


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let id = String(describing: MyContainerTVCell.self)
guard let cell = tableView
.dequeueReusableCell(withIdentifier: id, for: indexPath)
as? MyContainerTVCell else
return UITableViewCell()


cell.policyDetails = dataSource
// my cheat/trick doesn't work on large data.
DispatchQueue.main.asyncAfter(deadline: .now()+0.4)
tableView.beginUpdates()
cell.tableView.layoutIfNeeded()
cell.tableView.reloadData() // the overridden one
tableView.endUpdates()

return cell



extension MyContainerViewController

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
return estimateDataHeight()




My cell class which has the self size tableView and containerView:



class MyContainerTVCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var shadowView: UIView!
@IBOutlet weak var tableView: SelfSizedTableView!

// MARK: - Properties
let titles = ["Email ID:", "Mobile Number:", "Address:", "ID: "] // first section data array
let moreData: [String] = // remaining reusable sections array

// no of subsequent sections for moreData array type
var numberOfSections: Int
return 4


// MARK: -
var dataSource: MyDataSource!

// MARK: - Life Cycle
override func awakeFromNib()
super.awakeFromNib()
setupView()


override func layoutSubviews()
super.layoutSubviews()


// MARK: - Setup
func setupView()
containerView.rounded(with: 10)
shadowView.layer.applyShadow()

tableView.dataSource = self
tableView.delegate = self



// MARK: - UITableViewDataSource
extension MyContainerTVCell
func numberOfSections(in tableView: UITableView) -> Int
return numberOfSections + 1


func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
if section == 0 return titles.count + 1
else if section == 1 return moreData.count + 1
else return moreData.count


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let headerID = String(describing: MyHeaderTVCell.self)
let itemID = String(describing: MyItemTVCell.self)

switch indexPath.section
case 0:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = dataSource.title
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let item = titles[indexPath.row-1]
cell.titleLabel.text = item
cell.separatorView.isHidden = true
let data: String
switch indexPath.row
case 1:
data = dataSource.emailID
case 2:
data = dataSource.mobileNo
case 3:
data = dataSource.address
case 4:
data = dataSource.name
case 5:
data = dataSource.age
case 6:
data = dataSource.id
case 7:
data = dataSource.office
case 8:
data = dataSource.academic
default: data = String()

cell.detailLabel.text = data
return cell


case 1:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = "More Data"
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row-1]
cell.separatorView.isHidden = true
switch indexPath.row
case 1:
cell.detailLabel.text = section.a
case 2:
cell.detailLabel.text = section.b
case 3:
cell.detailLabel.text = "(section.c ?? 0)"
case 4:
cell.detailLabel.text = section.d
case 5:
cell.detailLabel.text = section.e
case 6:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell

default:
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row]
cell.separatorView.isHidden = true
switch indexPath.row
case 0:
cell.detailLabel.text = section.a
case 1:
cell.detailLabel.text = section.b
case 2:
cell.detailLabel.text = "(section.c ?? 0)"
case 3:
cell.detailLabel.text = section.d
case 4:
cell.detailLabel.text = section.e
case 5:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell




// MARK: - UITableViewDelegate
extension MyContainerTVCell
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
if indexPath.section == 0 && indexPath.row == 0 return 43
if indexPath.section == 1 && indexPath.row == 0 return 43
return 32











share|improve this question



















  • 2





    Do you have any screenshots to share?

    – Glenn
    Nov 14 '18 at 5:17











  • Please show code. What have you tried? I can't see why objective-c and swift are tags here because there is no code in your question.

    – Mike Taverne
    Nov 14 '18 at 6:29











  • @Glenn I've added details in the edit. Please ask if any doubt in understanding code or expected result.

    – Amber K
    Nov 14 '18 at 9:34











  • @MikeTaverne I've added code and edited the tags. Please review and ask if any doubt.

    – Amber K
    Nov 14 '18 at 9:35











  • Is it a right approach or any other solution?

    – Amber K
    Nov 14 '18 at 9:36















0















I have a scenario where I need to show a parent view with shadow and corner radius containing a long list of reusable items. I used a tableView to display items. But I stuck at making my tableview expand as much as its contentSize. It works but not accurate. Any solutions?



Edit:



Desired result:
enter image description here



I used the following reference for self sizing tableview.
Self Sizing UITableView



I made a few modifications as below:



final class SelfSizedTableView: UITableView 

var maxHeight = CGFloat.greatestFiniteMagnitude

override func reloadData()
super.reloadData()
self.invalidateIntrinsicContentSize()
self.layoutIfNeeded()


override var intrinsicContentSize: CGSize
let height = min(contentSize.height, maxHeight)
let size = CGSize(width: contentSize.width, height: height)
return size





I used a parent tableView with a cell having my containerView and embedding this self sized tableView.



class MyContainerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var parentTableView: UITableView!

// MARK: - Life Cycle
override func viewDidLoad()
super.viewDidLoad()
setupViews()


private func estimateDataHeight() -> CGFloat
let detailCellHeight: CGFloat = 32
let headingCellHeight: CGFloat = 43
let headings: CGFloat = headingCellHeight*2
let detailsHeight: CGFloat = detailCellHeight*4
let baseHeight = headings + detailsHeight
let membersHeight =
CGFloat(sectionsArray.count) * detailCellHeight
return baseHeight + membersHeight



// MARK: - UITableViewDataSource
extension MyContainerViewController

func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
return 1


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let id = String(describing: MyContainerTVCell.self)
guard let cell = tableView
.dequeueReusableCell(withIdentifier: id, for: indexPath)
as? MyContainerTVCell else
return UITableViewCell()


cell.policyDetails = dataSource
// my cheat/trick doesn't work on large data.
DispatchQueue.main.asyncAfter(deadline: .now()+0.4)
tableView.beginUpdates()
cell.tableView.layoutIfNeeded()
cell.tableView.reloadData() // the overridden one
tableView.endUpdates()

return cell



extension MyContainerViewController

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
return estimateDataHeight()




My cell class which has the self size tableView and containerView:



class MyContainerTVCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var shadowView: UIView!
@IBOutlet weak var tableView: SelfSizedTableView!

// MARK: - Properties
let titles = ["Email ID:", "Mobile Number:", "Address:", "ID: "] // first section data array
let moreData: [String] = // remaining reusable sections array

// no of subsequent sections for moreData array type
var numberOfSections: Int
return 4


// MARK: -
var dataSource: MyDataSource!

// MARK: - Life Cycle
override func awakeFromNib()
super.awakeFromNib()
setupView()


override func layoutSubviews()
super.layoutSubviews()


// MARK: - Setup
func setupView()
containerView.rounded(with: 10)
shadowView.layer.applyShadow()

tableView.dataSource = self
tableView.delegate = self



// MARK: - UITableViewDataSource
extension MyContainerTVCell
func numberOfSections(in tableView: UITableView) -> Int
return numberOfSections + 1


func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
if section == 0 return titles.count + 1
else if section == 1 return moreData.count + 1
else return moreData.count


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let headerID = String(describing: MyHeaderTVCell.self)
let itemID = String(describing: MyItemTVCell.self)

switch indexPath.section
case 0:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = dataSource.title
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let item = titles[indexPath.row-1]
cell.titleLabel.text = item
cell.separatorView.isHidden = true
let data: String
switch indexPath.row
case 1:
data = dataSource.emailID
case 2:
data = dataSource.mobileNo
case 3:
data = dataSource.address
case 4:
data = dataSource.name
case 5:
data = dataSource.age
case 6:
data = dataSource.id
case 7:
data = dataSource.office
case 8:
data = dataSource.academic
default: data = String()

cell.detailLabel.text = data
return cell


case 1:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = "More Data"
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row-1]
cell.separatorView.isHidden = true
switch indexPath.row
case 1:
cell.detailLabel.text = section.a
case 2:
cell.detailLabel.text = section.b
case 3:
cell.detailLabel.text = "(section.c ?? 0)"
case 4:
cell.detailLabel.text = section.d
case 5:
cell.detailLabel.text = section.e
case 6:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell

default:
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row]
cell.separatorView.isHidden = true
switch indexPath.row
case 0:
cell.detailLabel.text = section.a
case 1:
cell.detailLabel.text = section.b
case 2:
cell.detailLabel.text = "(section.c ?? 0)"
case 3:
cell.detailLabel.text = section.d
case 4:
cell.detailLabel.text = section.e
case 5:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell




// MARK: - UITableViewDelegate
extension MyContainerTVCell
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
if indexPath.section == 0 && indexPath.row == 0 return 43
if indexPath.section == 1 && indexPath.row == 0 return 43
return 32











share|improve this question



















  • 2





    Do you have any screenshots to share?

    – Glenn
    Nov 14 '18 at 5:17











  • Please show code. What have you tried? I can't see why objective-c and swift are tags here because there is no code in your question.

    – Mike Taverne
    Nov 14 '18 at 6:29











  • @Glenn I've added details in the edit. Please ask if any doubt in understanding code or expected result.

    – Amber K
    Nov 14 '18 at 9:34











  • @MikeTaverne I've added code and edited the tags. Please review and ask if any doubt.

    – Amber K
    Nov 14 '18 at 9:35











  • Is it a right approach or any other solution?

    – Amber K
    Nov 14 '18 at 9:36













0












0








0


1






I have a scenario where I need to show a parent view with shadow and corner radius containing a long list of reusable items. I used a tableView to display items. But I stuck at making my tableview expand as much as its contentSize. It works but not accurate. Any solutions?



Edit:



Desired result:
enter image description here



I used the following reference for self sizing tableview.
Self Sizing UITableView



I made a few modifications as below:



final class SelfSizedTableView: UITableView 

var maxHeight = CGFloat.greatestFiniteMagnitude

override func reloadData()
super.reloadData()
self.invalidateIntrinsicContentSize()
self.layoutIfNeeded()


override var intrinsicContentSize: CGSize
let height = min(contentSize.height, maxHeight)
let size = CGSize(width: contentSize.width, height: height)
return size





I used a parent tableView with a cell having my containerView and embedding this self sized tableView.



class MyContainerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var parentTableView: UITableView!

// MARK: - Life Cycle
override func viewDidLoad()
super.viewDidLoad()
setupViews()


private func estimateDataHeight() -> CGFloat
let detailCellHeight: CGFloat = 32
let headingCellHeight: CGFloat = 43
let headings: CGFloat = headingCellHeight*2
let detailsHeight: CGFloat = detailCellHeight*4
let baseHeight = headings + detailsHeight
let membersHeight =
CGFloat(sectionsArray.count) * detailCellHeight
return baseHeight + membersHeight



// MARK: - UITableViewDataSource
extension MyContainerViewController

func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
return 1


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let id = String(describing: MyContainerTVCell.self)
guard let cell = tableView
.dequeueReusableCell(withIdentifier: id, for: indexPath)
as? MyContainerTVCell else
return UITableViewCell()


cell.policyDetails = dataSource
// my cheat/trick doesn't work on large data.
DispatchQueue.main.asyncAfter(deadline: .now()+0.4)
tableView.beginUpdates()
cell.tableView.layoutIfNeeded()
cell.tableView.reloadData() // the overridden one
tableView.endUpdates()

return cell



extension MyContainerViewController

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
return estimateDataHeight()




My cell class which has the self size tableView and containerView:



class MyContainerTVCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var shadowView: UIView!
@IBOutlet weak var tableView: SelfSizedTableView!

// MARK: - Properties
let titles = ["Email ID:", "Mobile Number:", "Address:", "ID: "] // first section data array
let moreData: [String] = // remaining reusable sections array

// no of subsequent sections for moreData array type
var numberOfSections: Int
return 4


// MARK: -
var dataSource: MyDataSource!

// MARK: - Life Cycle
override func awakeFromNib()
super.awakeFromNib()
setupView()


override func layoutSubviews()
super.layoutSubviews()


// MARK: - Setup
func setupView()
containerView.rounded(with: 10)
shadowView.layer.applyShadow()

tableView.dataSource = self
tableView.delegate = self



// MARK: - UITableViewDataSource
extension MyContainerTVCell
func numberOfSections(in tableView: UITableView) -> Int
return numberOfSections + 1


func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
if section == 0 return titles.count + 1
else if section == 1 return moreData.count + 1
else return moreData.count


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let headerID = String(describing: MyHeaderTVCell.self)
let itemID = String(describing: MyItemTVCell.self)

switch indexPath.section
case 0:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = dataSource.title
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let item = titles[indexPath.row-1]
cell.titleLabel.text = item
cell.separatorView.isHidden = true
let data: String
switch indexPath.row
case 1:
data = dataSource.emailID
case 2:
data = dataSource.mobileNo
case 3:
data = dataSource.address
case 4:
data = dataSource.name
case 5:
data = dataSource.age
case 6:
data = dataSource.id
case 7:
data = dataSource.office
case 8:
data = dataSource.academic
default: data = String()

cell.detailLabel.text = data
return cell


case 1:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = "More Data"
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row-1]
cell.separatorView.isHidden = true
switch indexPath.row
case 1:
cell.detailLabel.text = section.a
case 2:
cell.detailLabel.text = section.b
case 3:
cell.detailLabel.text = "(section.c ?? 0)"
case 4:
cell.detailLabel.text = section.d
case 5:
cell.detailLabel.text = section.e
case 6:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell

default:
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row]
cell.separatorView.isHidden = true
switch indexPath.row
case 0:
cell.detailLabel.text = section.a
case 1:
cell.detailLabel.text = section.b
case 2:
cell.detailLabel.text = "(section.c ?? 0)"
case 3:
cell.detailLabel.text = section.d
case 4:
cell.detailLabel.text = section.e
case 5:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell




// MARK: - UITableViewDelegate
extension MyContainerTVCell
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
if indexPath.section == 0 && indexPath.row == 0 return 43
if indexPath.section == 1 && indexPath.row == 0 return 43
return 32











share|improve this question
















I have a scenario where I need to show a parent view with shadow and corner radius containing a long list of reusable items. I used a tableView to display items. But I stuck at making my tableview expand as much as its contentSize. It works but not accurate. Any solutions?



Edit:



Desired result:
enter image description here



I used the following reference for self sizing tableview.
Self Sizing UITableView



I made a few modifications as below:



final class SelfSizedTableView: UITableView 

var maxHeight = CGFloat.greatestFiniteMagnitude

override func reloadData()
super.reloadData()
self.invalidateIntrinsicContentSize()
self.layoutIfNeeded()


override var intrinsicContentSize: CGSize
let height = min(contentSize.height, maxHeight)
let size = CGSize(width: contentSize.width, height: height)
return size





I used a parent tableView with a cell having my containerView and embedding this self sized tableView.



class MyContainerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var parentTableView: UITableView!

// MARK: - Life Cycle
override func viewDidLoad()
super.viewDidLoad()
setupViews()


private func estimateDataHeight() -> CGFloat
let detailCellHeight: CGFloat = 32
let headingCellHeight: CGFloat = 43
let headings: CGFloat = headingCellHeight*2
let detailsHeight: CGFloat = detailCellHeight*4
let baseHeight = headings + detailsHeight
let membersHeight =
CGFloat(sectionsArray.count) * detailCellHeight
return baseHeight + membersHeight



// MARK: - UITableViewDataSource
extension MyContainerViewController

func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
return 1


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let id = String(describing: MyContainerTVCell.self)
guard let cell = tableView
.dequeueReusableCell(withIdentifier: id, for: indexPath)
as? MyContainerTVCell else
return UITableViewCell()


cell.policyDetails = dataSource
// my cheat/trick doesn't work on large data.
DispatchQueue.main.asyncAfter(deadline: .now()+0.4)
tableView.beginUpdates()
cell.tableView.layoutIfNeeded()
cell.tableView.reloadData() // the overridden one
tableView.endUpdates()

return cell



extension MyContainerViewController

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
return estimateDataHeight()




My cell class which has the self size tableView and containerView:



class MyContainerTVCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate 

// MARK: - IBOutlets
@IBOutlet weak var containerView: UIView!
@IBOutlet weak var shadowView: UIView!
@IBOutlet weak var tableView: SelfSizedTableView!

// MARK: - Properties
let titles = ["Email ID:", "Mobile Number:", "Address:", "ID: "] // first section data array
let moreData: [String] = // remaining reusable sections array

// no of subsequent sections for moreData array type
var numberOfSections: Int
return 4


// MARK: -
var dataSource: MyDataSource!

// MARK: - Life Cycle
override func awakeFromNib()
super.awakeFromNib()
setupView()


override func layoutSubviews()
super.layoutSubviews()


// MARK: - Setup
func setupView()
containerView.rounded(with: 10)
shadowView.layer.applyShadow()

tableView.dataSource = self
tableView.delegate = self



// MARK: - UITableViewDataSource
extension MyContainerTVCell
func numberOfSections(in tableView: UITableView) -> Int
return numberOfSections + 1


func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
if section == 0 return titles.count + 1
else if section == 1 return moreData.count + 1
else return moreData.count


func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
let headerID = String(describing: MyHeaderTVCell.self)
let itemID = String(describing: MyItemTVCell.self)

switch indexPath.section
case 0:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = dataSource.title
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let item = titles[indexPath.row-1]
cell.titleLabel.text = item
cell.separatorView.isHidden = true
let data: String
switch indexPath.row
case 1:
data = dataSource.emailID
case 2:
data = dataSource.mobileNo
case 3:
data = dataSource.address
case 4:
data = dataSource.name
case 5:
data = dataSource.age
case 6:
data = dataSource.id
case 7:
data = dataSource.office
case 8:
data = dataSource.academic
default: data = String()

cell.detailLabel.text = data
return cell


case 1:
if indexPath.row == 0
guard let cell = tableView
.dequeueReusableCell(withIdentifier: headerID, for: indexPath)
as? MyHeaderTVCell else
return UITableViewCell()

cell.titleLabel.text = "More Data"
return cell
else
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row-1]
cell.separatorView.isHidden = true
switch indexPath.row
case 1:
cell.detailLabel.text = section.a
case 2:
cell.detailLabel.text = section.b
case 3:
cell.detailLabel.text = "(section.c ?? 0)"
case 4:
cell.detailLabel.text = section.d
case 5:
cell.detailLabel.text = section.e
case 6:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell

default:
guard let cell = tableView
.dequeueReusableCell(withIdentifier: itemID, for: indexPath)
as? MyItemTVCell else
return UITableViewCell()

let sectionIndex = indexPath.section-1
guard sectionIndex <= numberOfSections-1,
let section = sectionsArray?[indexPath.section-1] else
return UITableViewCell()

cell.titleLabel.text = moreData[indexPath.row]
cell.separatorView.isHidden = true
switch indexPath.row
case 0:
cell.detailLabel.text = section.a
case 1:
cell.detailLabel.text = section.b
case 2:
cell.detailLabel.text = "(section.c ?? 0)"
case 3:
cell.detailLabel.text = section.d
case 4:
cell.detailLabel.text = section.e
case 5:
cell.detailLabel.text = section.f
if indexPath.section < numberOfSections
cell.separatorView.isHidden = false

default: break

return cell




// MARK: - UITableViewDelegate
extension MyContainerTVCell
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return UITableViewAutomaticDimension


func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
if indexPath.section == 0 && indexPath.row == 0 return 43
if indexPath.section == 1 && indexPath.row == 0 return 43
return 32








ios swift uitableview tableview






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 9:31







Amber K

















asked Nov 14 '18 at 5:10









Amber KAmber K

306212




306212







  • 2





    Do you have any screenshots to share?

    – Glenn
    Nov 14 '18 at 5:17











  • Please show code. What have you tried? I can't see why objective-c and swift are tags here because there is no code in your question.

    – Mike Taverne
    Nov 14 '18 at 6:29











  • @Glenn I've added details in the edit. Please ask if any doubt in understanding code or expected result.

    – Amber K
    Nov 14 '18 at 9:34











  • @MikeTaverne I've added code and edited the tags. Please review and ask if any doubt.

    – Amber K
    Nov 14 '18 at 9:35











  • Is it a right approach or any other solution?

    – Amber K
    Nov 14 '18 at 9:36












  • 2





    Do you have any screenshots to share?

    – Glenn
    Nov 14 '18 at 5:17











  • Please show code. What have you tried? I can't see why objective-c and swift are tags here because there is no code in your question.

    – Mike Taverne
    Nov 14 '18 at 6:29











  • @Glenn I've added details in the edit. Please ask if any doubt in understanding code or expected result.

    – Amber K
    Nov 14 '18 at 9:34











  • @MikeTaverne I've added code and edited the tags. Please review and ask if any doubt.

    – Amber K
    Nov 14 '18 at 9:35











  • Is it a right approach or any other solution?

    – Amber K
    Nov 14 '18 at 9:36







2




2





Do you have any screenshots to share?

– Glenn
Nov 14 '18 at 5:17





Do you have any screenshots to share?

– Glenn
Nov 14 '18 at 5:17













Please show code. What have you tried? I can't see why objective-c and swift are tags here because there is no code in your question.

– Mike Taverne
Nov 14 '18 at 6:29





Please show code. What have you tried? I can't see why objective-c and swift are tags here because there is no code in your question.

– Mike Taverne
Nov 14 '18 at 6:29













@Glenn I've added details in the edit. Please ask if any doubt in understanding code or expected result.

– Amber K
Nov 14 '18 at 9:34





@Glenn I've added details in the edit. Please ask if any doubt in understanding code or expected result.

– Amber K
Nov 14 '18 at 9:34













@MikeTaverne I've added code and edited the tags. Please review and ask if any doubt.

– Amber K
Nov 14 '18 at 9:35





@MikeTaverne I've added code and edited the tags. Please review and ask if any doubt.

– Amber K
Nov 14 '18 at 9:35













Is it a right approach or any other solution?

– Amber K
Nov 14 '18 at 9:36





Is it a right approach or any other solution?

– Amber K
Nov 14 '18 at 9:36












1 Answer
1






active

oldest

votes


















0














Why would you want to expand tableView as much as its content size to make it scrollable, when tableView is already scrollable?



However, if you have some other content, aside from table, on the screen and you want them to scroll together, then you need to embed all your content into UIScrollView.



Then, make a height constraint for you tableView in xib/storyboard with any value.
Then you might do something like this:



// in your view controller
private var heightObservation: NSKeyValueObservation?

// called once, for example, in viewDidLoad()
private func setupTableView()
...

observation = tableView.constraintFrameHeightToContentSizeHeight()


extension UITableView

func constraintFrameHeightToContentSizeHeight() -> NSKeyValueObservation
return observe(.contentSize, changeHandler: (tableView, _) in
tableView.heightConstraint?.constant = tableView.contentSize.height
)



// find height constraint
extension UIView

var heightConstraint: NSLayoutConstraint?
return constraints.first(where: $0.firstAttribute == .height )




Don't forget to uncheck "Scrolling Enabled" in xib/storyboard for that table view.






share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53293541%2fhow-to-show-a-parent-view-which-is-outside-tableview-and-is-scrollable%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Why would you want to expand tableView as much as its content size to make it scrollable, when tableView is already scrollable?



    However, if you have some other content, aside from table, on the screen and you want them to scroll together, then you need to embed all your content into UIScrollView.



    Then, make a height constraint for you tableView in xib/storyboard with any value.
    Then you might do something like this:



    // in your view controller
    private var heightObservation: NSKeyValueObservation?

    // called once, for example, in viewDidLoad()
    private func setupTableView()
    ...

    observation = tableView.constraintFrameHeightToContentSizeHeight()


    extension UITableView

    func constraintFrameHeightToContentSizeHeight() -> NSKeyValueObservation
    return observe(.contentSize, changeHandler: (tableView, _) in
    tableView.heightConstraint?.constant = tableView.contentSize.height
    )



    // find height constraint
    extension UIView

    var heightConstraint: NSLayoutConstraint?
    return constraints.first(where: $0.firstAttribute == .height )




    Don't forget to uncheck "Scrolling Enabled" in xib/storyboard for that table view.






    share|improve this answer



























      0














      Why would you want to expand tableView as much as its content size to make it scrollable, when tableView is already scrollable?



      However, if you have some other content, aside from table, on the screen and you want them to scroll together, then you need to embed all your content into UIScrollView.



      Then, make a height constraint for you tableView in xib/storyboard with any value.
      Then you might do something like this:



      // in your view controller
      private var heightObservation: NSKeyValueObservation?

      // called once, for example, in viewDidLoad()
      private func setupTableView()
      ...

      observation = tableView.constraintFrameHeightToContentSizeHeight()


      extension UITableView

      func constraintFrameHeightToContentSizeHeight() -> NSKeyValueObservation
      return observe(.contentSize, changeHandler: (tableView, _) in
      tableView.heightConstraint?.constant = tableView.contentSize.height
      )



      // find height constraint
      extension UIView

      var heightConstraint: NSLayoutConstraint?
      return constraints.first(where: $0.firstAttribute == .height )




      Don't forget to uncheck "Scrolling Enabled" in xib/storyboard for that table view.






      share|improve this answer

























        0












        0








        0







        Why would you want to expand tableView as much as its content size to make it scrollable, when tableView is already scrollable?



        However, if you have some other content, aside from table, on the screen and you want them to scroll together, then you need to embed all your content into UIScrollView.



        Then, make a height constraint for you tableView in xib/storyboard with any value.
        Then you might do something like this:



        // in your view controller
        private var heightObservation: NSKeyValueObservation?

        // called once, for example, in viewDidLoad()
        private func setupTableView()
        ...

        observation = tableView.constraintFrameHeightToContentSizeHeight()


        extension UITableView

        func constraintFrameHeightToContentSizeHeight() -> NSKeyValueObservation
        return observe(.contentSize, changeHandler: (tableView, _) in
        tableView.heightConstraint?.constant = tableView.contentSize.height
        )



        // find height constraint
        extension UIView

        var heightConstraint: NSLayoutConstraint?
        return constraints.first(where: $0.firstAttribute == .height )




        Don't forget to uncheck "Scrolling Enabled" in xib/storyboard for that table view.






        share|improve this answer













        Why would you want to expand tableView as much as its content size to make it scrollable, when tableView is already scrollable?



        However, if you have some other content, aside from table, on the screen and you want them to scroll together, then you need to embed all your content into UIScrollView.



        Then, make a height constraint for you tableView in xib/storyboard with any value.
        Then you might do something like this:



        // in your view controller
        private var heightObservation: NSKeyValueObservation?

        // called once, for example, in viewDidLoad()
        private func setupTableView()
        ...

        observation = tableView.constraintFrameHeightToContentSizeHeight()


        extension UITableView

        func constraintFrameHeightToContentSizeHeight() -> NSKeyValueObservation
        return observe(.contentSize, changeHandler: (tableView, _) in
        tableView.heightConstraint?.constant = tableView.contentSize.height
        )



        // find height constraint
        extension UIView

        var heightConstraint: NSLayoutConstraint?
        return constraints.first(where: $0.firstAttribute == .height )




        Don't forget to uncheck "Scrolling Enabled" in xib/storyboard for that table view.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 14 '18 at 7:13









        EvgeniyEvgeniy

        490413




        490413





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53293541%2fhow-to-show-a-parent-view-which-is-outside-tableview-and-is-scrollable%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Syphilis

            Darth Vader #20