why are the cells in my tableview resizing - swift3

I have a tableview with 2 cells. for some reason the cells get resized when I open in simulator. Trying to understand why. I added image of view.
this is the view code. for now i just wish the cells to get created at the height I set in IB
import UIKit
class userMenuViewController: BaseViewController,UITableViewDataSource,UITableViewDelegate {
var surveyNameArr = ["aaa","bbb","ccc"]
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return (surveyNameArr.count)
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as! PrefCell2TableViewCell
return (cell)
}
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
addSlideMenuButton()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

this is what i was looking for:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 100.0;//Choose your custom row height
}

Related

Best way To load more data from API when scrolling to bottom as pagination

I want when scrolling to bottom in UITableView Fetch more date from API based on Page Number
Are use this method
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (((scrollView.contentOffset.y + scrollView.frame.size.height) > scrollView.contentSize.height ) && ! isLoadingList){
self. isLoadingList = true
self. loadMoreItemsForList()
}
}
or used this method
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// fetch new data if user scroll to the last cell
guard isLoadingIndexPath(indexPath) else { return }
if self.totalItems > orders.count {
fetchNextPage()
}
}
use func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) method to fetch more data while scrolling to bottom.

How to get selected index of items in more navigation controller

I use below code for get selected items of tab bar controller. My UITabbar has 7 view controllers(there are 3 items in More tab).
this code work only for 5 tabs but it don`t return selected index of items on More!
import UIKit
class CustomTabbarController: UITabBarController{
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print(self.selectedIndex)
}
}
Following code worked for me. I had to redesign moreTableView to follow my app design. Function 'didSelectRowAt' returns what index is selected.
This code is added to 'UITabBarController' class.
var moreTableView: UITableView?
weak var currentTableViewDelegate: UITableViewDelegate?
func customizeMoreTableView() {
moreTableView = moreNavigationController.topViewController?.view as? UITableView
currentTableViewDelegate = moreTableView?.delegate
moreTableView?.delegate = self
moreTableView?.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (viewControllers?.count ?? 4) - 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let moreCell = UITableViewCell()
let item = viewControllers?[indexPath.row + 4].tabBarItem
moreCell.textLabel?.text = item?.title
moreCell.textLabel?.textColor = .white
moreCell.imageView?.image = item?.image
moreCell.imageView?.tintColor = .white
moreCell.backgroundColor = .black
return moreCell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
currentTableViewDelegate?.tableView!(tableView, didSelectRowAt: indexPath)
}
Get selected item like this :
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print(tabBar.items?.index(of: item))
}

type '[[string:string]]'? has no subscript member

I'm trying to present into a table view information from another screen and I'm getting this error message:
type '[[string:string]]'? has no subscript member
class TestListViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
let userTest = DataManager.getInstance().getRecord()
let arrayOfDateString = DataManager.getInstance().getArrayOfKeys()
override func viewDidLoad() {
super.viewDidLoad()
}
#IBOutlet weak var tableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userTest!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell
// cell.textLabel?.text = userTest[indexPath.row] - **here is the problem
cell.detailTextLabel?.text = "Your record"
return cell
}
}
Change this code -
cell.textLabel?.text = userTest[indexPath.row]
To this code -
cell.textLabel?.text = userTest![indexPath.row]

Swift 3 tableViewCell Button, strange behaviour, submit one button and others of the same Cell change as well?

Repeated on two projects and searched in vain so I hope someone can help...
Created a basic TableViewController and one TableViewCell. Run and press the first button, scroll down and other random buttons also show the same change?
TableViewController
import UIKit
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 99
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ButtonCell", for: indexPath) as! ButtonCell
cell.rowLabel.text = "\(indexPath.row)"
cell.tapAction = { (cell) in
self.showAlertForRow(tableView.indexPath(for: cell)!.row)
}
return cell
}
// MARK: - Extracted method
func showAlertForRow(_ row: Int) {
let alert = UIAlertController(
title: "BEHOLD",
message: "Cell at row \(row) was tapped!",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Gotcha!", style: UIAlertActionStyle.default, handler: { (test) -> Void in
self.dismiss(animated: true, completion: nil)
}))
self.present(
alert,
animated: true,
completion: nil)
}
}
Table View Cell
// ButtonCell.swift
import UIKit
class ButtonCell: UITableViewCell {
var tapAction: ((UITableViewCell) -> Void)?
#IBOutlet weak var rowLabel: UILabel!
#IBOutlet weak var button: UIButton!
#IBAction func buttonTap(_ sender: AnyObject) {
button.setTitle("Correct", for: .normal)
tapAction?(self)
}
}
Lets begin with the basics. You don't need this:
cell.tapAction = { (cell) in
self.showAlertForRow(tableView.indexPath(for: cell)!.row)
}
You better use the apple framework:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
showAlertForRow(indexPath.row)
}
Second create a method in you cell like
import UIKit
class ButtonCell: UITableViewCell {
var tapAction: ((UITableViewCell) -> Void)?
#IBOutlet weak var rowLabel: UILabel!
#IBOutlet weak var button: UIButton!
#IBAction func buttonTap(_ sender: AnyObject) {
button.setTitle("Correct", for: .normal)
tapAction?(self)
}
func createCell() {
button.setTitle("Your button title", for: normal)
}
}
and call the createCell method in your
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.createCell()
...
}
Hope I could help but try to start with the basics here: https://developer.apple.com/reference/uikit/uitableviewdelegate
This is happening because you are dequeuing your UITableViewCells. In order to solve the problem you should use the prepareForReuse() method in your ButtonCell. You can save the states of all your buttons and when a cell is being dequeued you can just set the title of the button in this cell in the prepareForReuse() method.

Issue with "didSelectRowAt indexPath" in Swift 3

I'm pretty new to swift but I've managed to follow along for the most part. However, there's an issue with my code that the code itself can't even identity apparently(I'm not receiving any error signs). I'm trying to click on a row from the table view to make it go to the following page but I don't think the code is recognizing the didselectrow method. Maybe one of you more experienced persons can help me out.
Here's the code:
import UIKit
import Foundation
class OnePercentersViewController: UIViewController, UITableViewDataSource
{
var copiedExecutiveArray : [String] = NSArray() as! [String]
var identities : [String] = NSArray() as! [String]
override func viewDidLoad()
{
super.viewDidLoad()
let copyExecutiveNames : ExecutiveArray = ExecutiveArray()
copiedExecutiveArray = copyExecutiveNames.executiveNames
identities = copyExecutiveNames.executiveNames
}
//how many sections in table
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
//returns int (how many rows)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return copiedExecutiveArray.count
}
//contents of each cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")//UITableViewCell()
let personName = copiedExecutiveArray[indexPath.row]
cell?.textLabel?.text = personName
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let execName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewController(withIdentifier: execName)
self.navigationController?.pushViewController(viewController!, animated: true)
print("button clicked")
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
}
I haven't checked other parts of your code, but to make tableView(_:didSelectRowAt:) work, your ViewController needs to conform to UITableViewDelegate:
class OnePercentersViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
Also you need to connect the delegate of the UITableView to your ViewController in your storyboard. Or you can do it in code, if you have an #IBOutlet to the UITableView. Anyway, not only dataSource, but also delegate.
And this is not a critical issue, but you can write the first two lines of the class as:
var copiedExecutiveArray : [String] = []
var identities : [String] = []
After spending a day and a half watching Youtube videos and reading comments to similar problems, tt took trial and error but I finally got it thanks to you guys!It finally clicked when I read that I had to connect the delegate to the ViewController through the storyboard, so thanks for that!
Here's the final code for those with similar issue:
import UIKit
import Foundation
class OnePercentersViewController: UIViewController,UITableViewDataSource, UITableViewDelegate
{
var copiedExecutiveArray : [String] = []
var identities : [String] = []
override func viewDidLoad()
{
super.viewDidLoad()
let copyExecutiveNames : ExecutiveArray = ExecutiveArray()
copiedExecutiveArray = copyExecutiveNames.executiveNames
identities = copyExecutiveNames.executiveNames
}
//how many sections in table
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
//returns int (how many rows)
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return copiedExecutiveArray.count
}
//contents of each cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let personName = copiedExecutiveArray[indexPath.row]
cell.textLabel?.text = personName
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let execName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewController(withIdentifier: execName)
self.navigationController?.pushViewController(viewController!, animated: true)
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
}