I have a UITableViewController and UITableViewCell. Now I am try to access a view from a UITableViewCell to UITableViewController by didSelectRowAt function. But I could not do it.
TableViewController
import Foundation
import UIKit
class FlipViewCon: UIViewController, UITableViewDelegate, UITableViewDataSource{
let flipCellId = "flipCellid"
let flipTableView: UITableView = {
let tableView = UITableView()
tableView.backgroundColor = .green
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .gray
flipTableView.delegate = self
flipTableView.dataSource = self
flipTableView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.view.addSubview(flipTableView)
flipTableView.register(FlipTableViewCell.self, forCellReuseIdentifier: flipCellId)
}
let countryArray = ["bangladesh", "nepal", "china", "malaysia", "thai land", "japan", "England", "canada"]
let cityArray = ["Dhake","Kathmandu", "Beijing", "Kuala Lumpur", "Bangkok", "tokeyo", "London", "Torento"]
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return countryArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: flipCellId, for: indexPath) as! FlipTableViewCell
//cell.textLabel?.text = countryArray[indexPath.row]
cell.zeroLabel.text = countryArray[indexPath.row]
cell.oneLabel.text = cityArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
UIView.transition(with: FlipTableViewCell.zeroView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: nil)
FlipTableViewCell.zeroView.isHidden = true
FlipTableViewCell.oneView.isHidden = false
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
UIView.transition(with: FlipTableViewCell.oneView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: nil)
FlipTableViewCell.zeroView.isHidden = false
FlipTableViewCell.oneView.isHidden = true
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return self.flipTableView.frame.width / 4
}
}
TableViewCell
import UIKit
class FlipTableViewCell: UITableViewCell{
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
static let zeroView = flipView(myColor: .yellow)
static let oneView = flipView(myColor: .green)
static func flipView(myColor: UIColor) -> UIView {
let view = UIView()
view.backgroundColor = myColor
return view
}
let zeroLabel: UILabel = {
let lb = UILabel()
lb.text = "Zero 0"
return lb
}()
let oneLabel: UILabel = {
let lb = UILabel()
lb.text = "one 1"
return lb
}()
func setupView(){
FlipTableViewCell.zeroView.frame = CGRect(x: 0, y: 0, width: frame.width, height:frame.height)
FlipTableViewCell.oneView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
self.addSubview(FlipTableViewCell.zeroView)
self.addSubview(FlipTableViewCell.oneView)
zeroLabel.frame = CGRect(x: 20, y: 0, width: self.frame.width - 40, height: 50)
oneLabel.frame = CGRect(x: 20, y:0, width: self.frame.width - 40, height: 50)
addSubview(zeroLabel)
addSubview(oneLabel)
}
}
Try this:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? FlipTableViewCell {
UIView.transition(with: cell.zeroView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: nil)
cell.zeroView.isHidden = true
cell.oneView.isHidden = false
}
}
Edit
I have update your FlipTableViewCell
it looks like this
class FlipTableViewCell: UITableViewCell{
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var zeroView : UIView!
var oneView : UIView!
func flipView(myColor: UIColor) -> UIView {
let view = UIView()
view.backgroundColor = myColor
return view
}
let zeroLabel: UILabel = {
let lb = UILabel()
lb.text = "Zero 0"
return lb
}()
let oneLabel: UILabel = {
let lb = UILabel()
lb.text = "one 1"
return lb
}()
func setupView(){
zeroView = flipView(myColor: .yellow)
oneView = flipView(myColor: .green)
zeroView.frame = CGRect(x: 0, y: 0, width: frame.width, height:frame.height)
oneView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
self.addSubview(zeroView)
self.addSubview(oneView)
zeroLabel.frame = CGRect(x: 20, y: 0, width: self.frame.width - 40, height: 50)
oneLabel.frame = CGRect(x: 20, y:0, width: self.frame.width - 40, height: 50)
addSubview(zeroLabel)
addSubview(oneLabel)
}
}
And Change some code in FlipViewCon
class FlipViewCon: UIViewController, UITableViewDelegate, UITableViewDataSource{
let flipCellId = "flipCellid"
let flipTableView: UITableView = {
let tableView = UITableView()
tableView.backgroundColor = .green
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .gray
flipTableView.delegate = self
flipTableView.dataSource = self
flipTableView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.view.addSubview(flipTableView)
flipTableView.register(FlipTableViewCell.self, forCellReuseIdentifier: flipCellId)
}
let countryArray = ["bangladesh", "nepal", "china", "malaysia", "thai land", "japan", "England", "canada"]
let cityArray = ["Dhake","Kathmandu", "Beijing", "Kuala Lumpur", "Bangkok", "tokeyo", "London", "Torento"]
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return countryArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: flipCellId, for: indexPath) as! FlipTableViewCell
//cell.textLabel?.text = countryArray[indexPath.row]
cell.zeroLabel.text = countryArray[indexPath.row]
cell.oneLabel.text = cityArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? FlipTableViewCell {
UIView.transition(with: cell.zeroView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: nil)
cell.zeroView.isHidden = true
cell.oneView.isHidden = false
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? FlipTableViewCell {
UIView.transition(with: cell.zeroView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: nil)
cell.zeroView.isHidden = false
cell.oneView.isHidden = true
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return self.flipTableView.frame.width / 4
}
}
Edit2
Replace this method in above solution
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? FlipTableViewCell {
UIView.transition(with: cell.oneView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: nil)
cell.zeroView.isHidden = false
cell.oneView.isHidden = true
}
}
Hope it will work for you
Do like this
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! FlipTableViewCell
// TODO:
}
Just like all the other answers on this post, use the cellForRow(at: IndexPath) method on UITableView, to get a reference to the cells in the table view.
This method returns a UITableViewCell, if the cell is loaded (visible) and nil if the indexPath is not correct or the cell is not loaded.
The code should look like:
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
// Do something with cell.
}
TableViewController
import Foundation
import UIKit
class FlipViewCon: UIViewController, UITableViewDelegate, UITableViewDataSource{
let flipCellId = "flipCellid"
let flipTableView: UITableView = {
let tableView = UITableView()
tableView.backgroundColor = .green
tableView.allowsMultipleSelection = true
return tableView
}()
let countryArray = ["India","bangladesh", "nepal", "china", "malaysia", "thai land", "japan", "England", "canada"]
let cityArray = ["Delhi","Dhake","Kathmandu", "Beijing", "Kuala Lumpur", "Bangkok", "tokeyo", "London", "Torento"]
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .gray
flipTableView.delegate = self
flipTableView.dataSource = self
flipTableView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.view.addSubview(flipTableView)
self.resetFlag()
flipTableView.register(FlipTableViewCell.self, forCellReuseIdentifier: flipCellId)
}
var flagArray : [String] = []
func resetFlag() {
flagArray.removeAll(keepingCapacity: true)
for _ in 0 ..< self.countryArray.count {
self.flagArray.append("0")
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return countryArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: flipCellId, for: indexPath) as! FlipTableViewCell
cell.selectionStyle = .none
if flagArray[indexPath.row] == "0" {
cell.zeroView.isHidden = false
cell.oneView.isHidden = true
}else{
cell.zeroView.isHidden = true
cell.oneView.isHidden = false
}
cell.zeroLabel.text = countryArray[indexPath.row]
cell.oneLabel.text = cityArray[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? FlipTableViewCell {
self.flagArray.remove(at: indexPath.row)
self.flagArray.insert("1", at: indexPath.row)
UIView.transition(with: cell.zeroView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: { (complete) in
cell.zeroView.isHidden = true
cell.oneView.isHidden = false
})
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? FlipTableViewCell {
self.flagArray.remove(at: indexPath.row)
self.flagArray.insert("0", at: indexPath.row)
UIView.transition(with: cell.oneView, duration: 0.5, options: .transitionFlipFromLeft, animations: nil, completion: { (complete) in
cell.zeroView.isHidden = false
cell.oneView.isHidden = true
})
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return self.flipTableView.frame.width / 4
}
}
TableViewCell
import UIKit
class FlipTableViewCell: UITableViewCell{
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let zeroView = flipView(myColor: .yellow)
let oneView = flipView(myColor: .green)
static func flipView(myColor: UIColor) -> UIView {
let view = UIView()
view.backgroundColor = myColor
return view
}
let zeroLabel: UILabel = {
let lb = UILabel()
lb.text = "Zero 0"
return lb
}()
let oneLabel: UILabel = {
let lb = UILabel()
lb.text = "one 1"
return lb
}()
func setupView(){
zeroView.frame = CGRect(x: 0, y: 0, width: frame.width, height:frame.width/4)
oneView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.width/4)
self.addSubview(oneView)
self.addSubview(zeroView)
zeroLabel.frame = CGRect(x: 20, y: (frame.width/4)/2 - 25, width: self.frame.width - 40, height: 50)
oneLabel.frame = CGRect(x: 20, y:(frame.width/4)/2 - 25, width: self.frame.width - 40, height: 50)
zeroView.addSubview(zeroLabel)
oneView.addSubview(oneLabel)
}
}
Related
I’ve implemented a custom cell for a UITableView, but when I run the Playground it’s just a standard table. It’s probably something stupid simple, but I’m very new to UIKit and somewhat new to Swift.
Also, I’ve tried to implement a “sticky header”, but no matter what I try the header scrolls with the rest of the table.
import UIKit
import PlaygroundSupport
class ViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 19
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: CardCell = tableView.dequeueReusableCell(withIdentifier: "CardCell", for: indexPath) as! CardCell
cell.messageLabel.text = "yo"
return cell
}
var convoTableView = UITableView()
override func viewDidLoad(){
super.viewDidLoad()
convoTableView = UITableView(frame: self.view.bounds, style:
UITableView.Style.plain)
convoTableView.backgroundColor = UIColor.white
convoTableView.register(CardCell.self, forCellReuseIdentifier: "CardCell")
let header = UIView(frame: CGRect(x: 0, y: 0, width: convoTableView.frame.width, height: 100))
header.backgroundColor = .red
self.convoTableView.delegate = self
self.convoTableView.dataSource = self
let yourLabel = UILabel(frame: CGRect(x: 10, y: 0, width: 100, height: 100))
yourLabel.textColor = UIColor.black
yourLabel.backgroundColor = UIColor.white
yourLabel.text = "mylabel text"
header.addSubview(yourLabel)
convoTableView.tableHeaderView = header
convoTableView.estimatedSectionHeaderHeight = 40.0
self.view.addSubview(convoTableView)
}
}
class CardCell: UITableViewCell {
let messageLabel:UILabel = {
let label = UILabel()
label.font = UIFont.boldSystemFont(ofSize: 14)
label.clipsToBounds = true
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let dateLabel:UILabel = {
let label = UILabel()
label.font = UIFont.boldSystemFont(ofSize: 8)
label.clipsToBounds = true
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let containerView:UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.clipsToBounds = true
return view
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
containerView.addSubview(messageLabel)
containerView.addSubview(dateLabel)
self.contentView.addSubview(containerView)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
PlaygroundPage.current.liveView = ViewController()
Here's all the code you need here to make a custom cell and sticky header:
import UIKit
import PlaygroundSupport
class ViewController: UITableViewController {
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = .purple
return view
}
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
50
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
19
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CardCell", for: indexPath) as! CardCell
cell.textLabel?.text = "\(indexPath.row)"
return cell
}
override func viewDidLoad(){
super.viewDidLoad()
tableView.register(CardCell.self, forCellReuseIdentifier: "CardCell")
}
}
class CardCell: UITableViewCell { }
PlaygroundPage.current.liveView = ViewController()
To make the header sticky and non-scrollable with the table view you need to take a different UIView above the table view and give the frames of the table just below the UiView.
customView = MyCustomView(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
self.view.addSubview(customView
I have a problem with setup default row in TableView. I just wanna always pick first element from dataSource. I tried a few solutions with "selectRow" and other but no one of them work.
Here's my code below:
class HomeVC: UIViewController{
#IBOutlet weak var btnSelectCountry: UIButton!
let transparentView = UIView()
let tableView = UITableView()
var selectedButton = UIButton()
var dataSource = [String]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(CellClass.self, forCellReuseIdentifier: "Cell")
let index = NSIndexPath(row: 0, section: 0)
tableView.selectRow(at: index as IndexPath, animated: true, scrollPosition: .bottom)
}
func addTransparentView(frames: CGRect){
let window = UIApplication.shared.keyWindow
transparentView.frame = window?.frame ?? self.view.frame
self.view.addSubview(transparentView)
tableView.frame = CGRect(x: frames.origin.x, y: frames.origin.y + frames.height, width: frames.width, height: 0 )
self.view.addSubview(tableView)
tableView.layer.cornerRadius = 5
transparentView.backgroundColor = UIColor.black.withAlphaComponent(0.9)
tableView.reloadData()
let tapgesture = UITapGestureRecognizer(target: self, action: #selector(removeTransparentView))
transparentView.addGestureRecognizer(tapgesture)
transparentView.alpha = 0
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveEaseInOut, animations: {
self.transparentView.alpha = 0.5
self.tableView.frame = CGRect(x: frames.origin.x, y: frames.origin.y + frames.height + 5, width: frames.width, height: CGFloat(self.dataSource.count * 50))
}, completion: nil)
}
}
extension HomeVC: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = dataSource[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedButton.setTitle(dataSource[indexPath.row], for: .normal)
removeTransparentView()
}
Try replacing viewDidLoad() with this
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(CellClass.self, forCellReuseIdentifier: "Cell")
let index = IndexPath(row: 0, section: 0)
tableView(tableView, didSelectRowAt: index)
}
This will automatically trigger the didSelectRow method but you need to populate your dataSource before this or the application will crash.
You can try adding this for example in viewWillAppear()
override func viewWillAppear(_ animated: Bool) {
dataSource = ["Your", "Data"]
}
I wanted to implement expandable/collapsable UITableView with Custom UITableViewCell that adjusts its side according to the question/answer text. I have tried with different methods but none of it worked as I desire. If there is anyone who has implemented the same thing then kindly share the project link or let me know how it's done. Any kind of help would be greatly appreciated. I am sharing the screenshot of what I wanted.
Here's what I have tried. When I scroll the table view, it adds extra spaces between the cells and also messed up the UITextView.
enter code here
// Mark: Table View Delegate Methods
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let questionTextView = UITextView(frame:CGRect(x: 0, y: 0, width: 265.0, height: 30))
let answerTextView = UITextView(frame:CGRect(x: 0, y: 0, width: 265.0, height: 30))
questionTextView.text = questionStringArray[indexPath.row]
answerTextView.text = answerStringArray[indexPath.row]
Common.adjustUITextViewHeight(questionTextView)
Common.adjustUITextViewHeight(answerTextView)
let cellHeightExpanded:CGFloat = CGFloat(3 + Double(questionTextView.frame.size.height) + 5 + Double(answerTextView.frame.size.height) + 10)
let cellHeightCollapsed:CGFloat = CGFloat(3 + Double(questionTextView.frame.size.height) + 5)
if (indexPath.row == selectedQuestion)
{
return cellHeightExpanded
}
else
{
return cellHeightCollapsed
}
}
// number of rows in table view
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
// create a cell for each table view row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! FAQsCell
cell.backgroundColor = UIColor.white
cell.tvQuestion.text = questionStringArray[indexPath.row]
cell.tvAnswer.text = answerStringArray[indexPath.row]
Common.adjustUITextViewHeight(cell.tvQuestion)
Common.adjustUITextViewHeight(cell.tvAnswer)
cell.tvAnswer.frame = CGRect(origin: CGPoint(x: cell.tvAnswer.frame.origin.x, y : cell.tvQuestion.frame.origin.y + cell.tvQuestion.frame.size.height), size: CGSize(width: cell.tvAnswer.frame.size.width, height: cell.tvAnswer.frame.size.height))
if indexPath.row == selectedQuestion {
cell.backgroundColor = UIColor.okapiCellGrayColorForPendingAppLevel()
cell.tvQuestion.textColor = UIColor.white
cell.tvAnswer.textColor = UIColor.white
}
else {
cell.backgroundColor = UIColor.clear
cell.tvQuestion.textColor = UIColor.blue_grey_700()
cell.tvAnswer.textColor = UIColor.blue_grey_700()
}
return cell
}
// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedQuestion = indexPath.row
faqsTableView.reloadData()
}
Add a vertical stackview in the custom cell and show/hide answer based on selected cell
class ViewController: UITableViewController {
var questions = [(question:String,answer:String)]()
var selectedQuestion = -1
override func viewDidLoad() {
super.viewDidLoad()
questions = [(question:"Question 1",answer:"Answer 1"),(question:"Question 2",answer:"Answer 2"),
(question:"Question 3",answer:"Answer 3"),(question:"Question 4",answer:"Answer 4"),
(question:"Question 5",answer:"Answer 5")]
self.view.backgroundColor = .white
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 50
tableView.register(FAQsCell.self, forCellReuseIdentifier: "FAQsCell")
}
}
extension ViewController {
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return questions.count
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FAQsCell") as! FAQsCell
cell.questionLbl.text = questions[indexPath.row].question
cell.answerLbl.text = questions[indexPath.row].answer
if indexPath.row == selectedQuestion {
cell.backgroundColor = .groupTableViewBackground
cell.dropDownImgView.image = //upimage
cell.answerView.isHidden = false
} else {
cell.backgroundColor = .white
cell.dropDownImgView.image = //downimage
cell.answerView.isHidden = true
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedQuestion = indexPath.row
tableView.reloadData()
}
}
class FAQsCell: UITableViewCell {
let stackView = UIStackView()
let questionLbl = UILabel()
let dropDownImgView = UIImageView()
let answerView = UIView()
let answerLbl = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
stackView.axis = .vertical
stackView.distribution = .fillProportionally
stackView.spacing = 5
stackView.alignment = .fill
stackView.translatesAutoresizingMaskIntoConstraints = false
addSubview(stackView)
let questionView = UIView()
questionView.translatesAutoresizingMaskIntoConstraints = false
questionView.heightAnchor.constraint(equalToConstant: 35).isActive = true
stackView.addArrangedSubview(questionView)
questionLbl.font = UIFont.boldSystemFont(ofSize: 18)
questionLbl.translatesAutoresizingMaskIntoConstraints = false
questionView.addSubview(questionLbl)
dropDownImgView.contentMode = .scaleAspectFit
dropDownImgView.translatesAutoresizingMaskIntoConstraints = false
questionView.addSubview(dropDownImgView)
answerView.translatesAutoresizingMaskIntoConstraints = false
answerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 35).isActive = true
stackView.addArrangedSubview(answerView)
answerLbl.numberOfLines = 0
answerLbl.lineBreakMode = .byWordWrapping
answerLbl.font = UIFont.systemFont(ofSize: 17)
answerLbl.translatesAutoresizingMaskIntoConstraints = false
answerView.addSubview(answerLbl)
questionView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(10)-[questionLbl]-(10)-[dropDownImgView(25)]-(10#999)-|", options: [.alignAllCenterY], metrics: nil, views: ["questionLbl":questionLbl, "dropDownImgView": dropDownImgView]))
dropDownImgView.heightAnchor.constraint(equalTo: dropDownImgView.widthAnchor).isActive = true
questionView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[questionLbl(25)]-(5)-|", options: [], metrics: nil, views: ["questionLbl":questionLbl]))
answerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(10)-[answerLbl]-(10)-|", options: [], metrics: nil, views: ["answerLbl":answerLbl]))
answerView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[answerLbl(>=25)]-(5)-|", options: [], metrics: nil, views: ["answerLbl":answerLbl]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[stackView]-(5#999)-|", options: [], metrics: nil, views: ["stackView":stackView]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(5)-[stackView]-(5)-|", options: [], metrics: nil, views: ["stackView":stackView]))
}
}
you can achieve through constraint.
give title and description constraint to bottom to superview.
after that change priority of constraint accordingly.
let me know if you want to understand through imagee.
I am trying to make this, as in the first picture:
Image 1
Image 2
But the view somehow does not show up like I want it to. Here you can see my full project code:
import UIKit
import RealmSwift
import CVCalendar
class Test: UIViewController, UITableViewDelegate, UITableViewDataSource {
var myTableView: UITableView = UITableView()
var itemsToLoad: [String] = ["One", "Two", "Three"]
var myView = UIView()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor(red: 4/255, green: 4/255, blue: 4/255, alpha: 1.0)
self.navigationController?.navigationBar.barStyle = .black
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationItem.title = "Test"
self.navigationController?.navigationBar.prefersLargeTitles = true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Get main screen bounds
let screenSize: CGRect = UIScreen.main.bounds
let screenWidth = screenSize.width
let screenHeight = screenSize.height
myView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: 150)
myView.backgroundColor = .black
self.view.addSubview(myView)
myTableView.frame = CGRect(x: 0, y: 50, width: screenWidth, height: screenHeight-50);
myTableView.dataSource = self
myTableView.delegate = self
myTableView.backgroundColor = .blue
myTableView.layer.borderWidth = 3
myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(myTableView)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return itemsToLoad.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = self.itemsToLoad[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("User selected table row \(indexPath.row) and item \(itemsToLoad[indexPath.row])")
}
}
Why won't it show up? The first picture is how I want it, then second picture is how it looks now.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if self.itemsToLoad[indexPath.row] != nil {
cell.textLabel?.text = self.itemsToLoad[indexPath.row]
cell.backgroundColor = .white
}else {
cell.backgroundColor = .blue
}
return cell
}
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{
var tableView:UITableView!
var city = ["gz","dl","sz","bj","hz"]
var city2 = ["gd","ln","gx","he","se"]
var city3 = ["a","b","c","d","e"]
let cellid = "reusecell"
let mycellid = "customer"
override func viewDidLoad()
{
super.viewDidLoad()
tableView = UITableView(frame: CGRect(x: 0, y: 20, width: self.view.frame.width, height: self.view.frame.height), style: UITableViewStyle.Grouped)
tableView.dataSource = self
tableView.delegate = self
self.view.addSubview(tableView)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if section == 0
{
return city.count
}else if section == 1
{
return city2.count
}
else
{ print("section3 count")
return city3.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
if indexPath.section == 0
{
var cell = tableView.dequeueReusableCellWithIdentifier(cellid)
if cell == nil
{
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellid)
}
cell?.textLabel?.text = "\(city[indexPath.row])"
cell?.detailTextLabel?.text = "beautiful place"
cell?.imageView?.image = UIImage(named: "test.png")
cell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
cell?.selectionStyle = UITableViewCellSelectionStyle.Gray
tableView.beginUpdates()
return cell!
}
else if indexPath.section == 1
{
var cell = tableView.dequeueReusableCellWithIdentifier(cellid)
if cell == nil
{
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: cellid)
}
cell?.textLabel?.text = "\(city2[indexPath.row])"
cell?.detailTextLabel?.text = "beautiful place"
cell?.imageView?.image = UIImage(named: "test.png")
cell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
cell?.selectionStyle = UITableViewCellSelectionStyle.Gray
tableView.beginUpdates()
return cell!
}
else
{
var mycell:MyCellTableViewCell? = tableView.dequeueReusableCellWithIdentifier(mycellid) as? MyCellTableViewCell
if mycell == nil
{
print("section3")
mycell = MyCellTableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: mycellid)
}
print("section3 config")
mycell?.title?.text = "\(city3[indexPath.row])"
mycell?.detailTitle?.text = "beautiful place"
mycell?.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
mycell?.imageView?.frame = CGRect(x: 0, y: 0, width: 50, height: 100)
mycell?.imageView?.image = UIImage(named:"test.png")
mycell?.selectionStyle = UITableViewCellSelectionStyle.Gray
return mycell!
}
}
//Section的头部标题
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "城市选择器"
}
//Section的尾部标题
func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return "选择相应的城市"
}
//有几个部分
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 3
}
//section尾部的高度
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 28
}
//section头部的高度
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 28
}
//section行的高度
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
if indexPath.section == 0
{
return 60
}
else if indexPath.section == 1
{
return 60
}
else
{
return 100
}
}
func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
class MyCellTableViewCell: UITableViewCell {
var title:UILabel?
var detailTitle:UILabel?
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
{
super.init(style: style, reuseIdentifier: reuseIdentifier)
title = UILabel(frame: CGRect(x: 100, y: 5, width: 50, height: 40))
detailTitle = UILabel(frame: CGRect(x: 100, y: 50, width: 50, height: 40))
self.addSubview(title!)
self.addSubview(detailTitle!)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Custom Cell, I want to let him in the third section shows, but when I pulled down the TableView, the third paragraph of section does not display the content. I don't know what's the problem.
enter image description hereenter image description here
I assume that there is something wrong the MyCellTableViewCell.
Maybe you can have a look at that or include it?
Are the print commands from part#3 printed in the console?
U need to dynamically change the height of the table using the following:
var noOfRows = city.count + city2.count + city3.count;
var currentHeight = self.tableView(tableView, heightForRowAtIndexPath: indexPath)
var finalHeight = noOfRows * Int(currentHeight);
You will need to place is the correct delegate function to make sure that when the table is rendered the height is changed.