How to show a parent view which is outside tableview and is scrollable?
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:
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
|
show 1 more comment
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:
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
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
|
show 1 more comment
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:
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
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:
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
ios swift uitableview tableview
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
|
show 1 more comment
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
|
show 1 more comment
1 Answer
1
active
oldest
votes
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.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 14 '18 at 7:13
EvgeniyEvgeniy
490413
490413
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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