How to create multiple textfield in tableview cell dynamically - swift4

This is what I tried .....
Can anyone help me understand the below code that creates a textfield ? A summary about the following code would be very useful.
func numberOfSections(in tableView: UITableView) -> Int {
return 10
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 4
}else if section == 1 {
return 3
}else{
return 1
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DynamicViewController") as! DynamicTableViewCell
for var i in (0..<indexPath.count).reversed()
{
var myTextField: UITextField = UITextField(frame: CGRect(x: 0, y: 0, width: 340, height: 40))
myTextField.placeholder = "Enter Email Address \(i)"
myTextField.backgroundColor = UIColor.brown
cell.addSubview(myTextField)
}
return cell
}

Related

Multiple headerview in tableview in swift

I want to create 3 headers in the tableview given in the images and 8 students in each row, my code is as follows
Screenshot of the example
class ViewController: UIViewController {
var schoolOfList: [Any] = [
[["school": ["VIP", "Bright International", "Motherland"]],
[["student1": ["Chirag", "Akshay", "Shailesh", "Vishal", "Mehul", "Vinod", "Mukesh", "Darshan"]],
["student2": ["Manjari", "Kairav", "Abhimanyu", "Akshara", "Arohi", "Neel", "Naksh", "Naman"]],
["student3": ["Paritosh", "Anuj", "Kavya", "Samar", "Vanraj", "Kinjal", "Anupama", "Riyan"]]]]]
#IBOutlet weak var mytableview : UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension ViewController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> (Int) {
return schoolOfList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)
cell.textLabel?.text = schoolOfList["school"] as! [String]indexPath.row
return cell
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerview = UIView(frame: CGRect(x:0,y:0,width:self.mytableview.frame.width,height:50))
headerview.backgroundColor = .green
let lable = UILabel(frame: CGRect(x:0,y:0,width:self.mytableview.frame.width,height:50))
lable.textAlignment = .center
lable.text = (schoolOfList["school"]as!String)
headerview.addSubview(lable)
return headerview
}

How to add corner radius and a background to a whole section including its header and cells in UI Table View

How do I add corner radius and background to both the section header and its cell together like in the iOS weather app?
My table view data source and delegate-
extension HomeViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
10
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: HourlyForecastViewTableViewCell.identifier) else { return UITableViewCell() }
cell.layer.backgroundColor = UIColor.blue.cgColor
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
200
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return HourlyForecastHeaderView()
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
}
You can tryout this below code, here I just explained how to use UIRectCorner to apply corner radius to the specific edge.
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let kCellId = "kCellId"
var lCell = tableView.dequeueReusableCell(withIdentifier: kCellId)
if lCell == nil {
lCell = UITableViewCell(style: .default, reuseIdentifier: kCellId)
lCell?.textLabel?.text = "Row - \(indexPath.row)"
}
lCell?.backgroundColor = .orange
return lCell!
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let kHeaderId = "kHeaderId"
var header = tableView.dequeueReusableHeaderFooterView(withIdentifier: kHeaderId)
if header == nil {
header = HeaderView(reuseIdentifier: kHeaderId)
header?.frame = CGRect(origin: .zero, size: CGSize(width: tableView.bounds.size.width, height: 35))
header?.tintColor = .orange
let titleLabel = UILabel()
titleLabel.text = "Section - \(section)"
titleLabel.sizeToFit()
titleLabel.frame = CGRect(origin: CGPoint(x: 20, y: 0), size: CGSize(width: tableView.bounds.size.width-20, height: 35))
header?.addSubview(titleLabel)
}
return header
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
view.applyCorners(to: [.topLeft, .topRight], with: view.bounds)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let isLastCell = tableView.numberOfRows(inSection: indexPath.section)-1 == indexPath.row
if isLastCell {
cell.applyCorners(to: [.bottomLeft, .bottomRight], with: cell.bounds)
}else{
cell.noCorners()
}
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
50
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
35
}
}
class HeaderView: UITableViewHeaderFooterView {
}
extension UIView {
func noCorners() {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0))
let shape = CAShapeLayer()
shape.path = path.cgPath
layer.mask = shape
}
func applyCorners(to: UIRectCorner, with rect: CGRect) {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: to, cornerRadii: CGSize(width: 10, height: 10))
let shape = CAShapeLayer()
shape.path = path.cgPath
layer.mask = shape
}
}

Swift tableview 'method heightForHeaderInSection' makes section text raise

When heightForHeaderInSection and/or heightForFooterInSection is called, the section text raises above it's first row. I attached a screenshot to show the issue. How can I increase the section spacing without the section header being affected?
#IBOutlet weak var tableView: UITableView!
let fruits =
["apple","pear","orange","caramel","peach","fruit","fruits"]
let numbers = ["1", "2"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
if section == 0 {
return fruits.count
} else {
return numbers.count
}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection
section: Int) -> String? {
if section == 0 {
return "Animals"
} else {
return "Numbers"
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:
"cell1", for: indexPath)
if indexPath.section == 0 {
cell.textLabel?.text = fruits[indexPath.row]
} else {
cell.textLabel?.text = numbers[indexPath.row]
}
return cell
}
These are the 2 methods in question:
func tableView(_ tableView: UITableView, heightForHeaderInSection
section: Int) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, heightForFooterInSection
section: Int) -> CGFloat {
return 100
}
You are setting the height of the header to 100. See here:
func tableView(_ tableView: UITableView, heightForHeaderInSection
section: Int) -> CGFloat {
return 100 // Instead try returning 30
}
func tableView(_ tableView: UITableView, heightForFooterInSection
section: Int) -> CGFloat {
return 100 // If you are not using a footer - return .zero
}
I got the answer from another post.
Just add:
tableView.sectionHeaderTopPadding = 100 // or whatever number you want.
There's also another way.
Click on of these ->
You can choose Grouped or the rounded design 'Inset Grouped'
After you can use the method 'heightForHeaderInSection' to select the specific section/s.

Scroll to bottom TableView with custom section and cell Swift

My tableview has custom sections and cells. Every time the user scroll to the bottom it will call the server and load additional datas. My problem is how do I detect the last section so it could load more data? Each section contain 1 to 3 rows. My willDisplay wasn't working properly and the refreshControl.beginRefreshing() indicator didn't show too. Thanks!
let refreshControl = UIRefreshControl()
//MARK - Header Sections
func numberOfSections(in tableView: UITableView) -> Int {
return tableData[segmentedControlIndex].count
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! HomeSectionTableViewCell
let model = events[segmentedControlIndex][section]
cell.setup(model: model)
.
.
.
return cell.contentView
}
//MARK - Cells
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableData[segmentedControlIndex][section].rows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "detailCell") as! HomeTableViewDetailCell
.
.
.
cell.detailTitleLabel?.text = tableData[segmentedControlIndex][indexPath.section].rows[indexPath.row].detailTitleLabelString
cell.detailSubtitleLabel?.text = tableData[segmentedControlIndex][indexPath.section].rows[indexPath.row].detailSubtitleLabelString
return cell
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.000001
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell: HomeTableViewDetailCell = tableView.cellForRow(at: indexPath) as? HomeTableViewDetailCell {
cell.detailTitleLabel?.numberOfLines = cell.detailTitleLabel?.numberOfLines == 0 ? 1 : 0
tableView.reloadData()
}
}
//MARK - TableView add more data
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.section == tableView.numberOfSections - 1 {
self.refreshControl.beginRefreshing()
self.page = self.page + 1
self.getMoreData() { result in
self.refreshControl.endRefreshing()
print("Load More Bets Data reload: \(result == true ? "Success":"Failure")")
}
}
}

Delete UITableHeader title when section contains empty row

I am implementing a UITableView to populate contact name of the persons. I have implemented pretty much every thing.
I need to delete the section header title of the section whose rows have been deleted by the user and does not contain any other rows. Is there some way to do that. Simply deleting the value from title array when index.item gives me a crash. Any idea on it..
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sortedUniqueFirstLetters[section]
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! TableViewCell
cell.account = sections[indexPath.section][indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
view.tintColor = UIColor.setColor(Red: 223, Green: 220, Blue: 224, Alpha: 1)
let header = view as! UITableViewHeaderFooterView
header.textLabel?.textColor = UIColor.white
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true;
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
***if indexPath.item == 0{ //Trying to update title array when a section is empty
sortedUniqueFirstLetters.remove(at: indexPath.section) //Index out of range error here.
}***
sections[indexPath.section].remove(at: indexPath.item)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.middle);
}
}
Here is the answer :
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
return sortedUniqueFirstLetters[section]
} else {
return nil
}
}
You should also use the heightForHeaderInSction as well along with your titleForHEaderInSction method. Let me know if below code works for you:
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let numberOfRows = tableView.numberOfRows(inSection: section)
if numberOfRows == 0 {
return ""
}else{
return sortedUniqueFirstLetters[section]
}
}
func tableView (tableView:UITableView , heightForHeaderInSection section:Int) -> Float {
let title = self.tableView(tableView, titleForHeaderInSection: section)
if (title == "") {
return 0.0
}
return 80.0
}