UITableView as inputView for UITextField didSelectRowAtIndexPath randomly not fired - swift

I have a UITableViewController that I'm using to override the inputView of a UITextField subclass. Sometimes the tableView didSelectRowAtIndexPath stops getting fired until a user scolls the table and tries to click again. I can't seem to get a fix on what would cause the cells to become unresponsive. Most of the time it works great, but randomly the cells stop responding to touches until the user scrolls the tableview a bit.
I don't have any TapGestureRecognizers in the view to my knowledge, and have played around with overriding HitTest in the UITableViewCell, but can't seem to figure out the issue.
Any ideas on how to better debug this?
Here is the tableView controller code:
protocol MultiSelectPickerDelegate
{
func didSelectOption(optionIndex:Int, group:Int)
}
class MultiSelectPicker: UITableViewController {
var multiSelectGroups = [MultiSelectGroup](){
didSet{
self.tableView.reloadData()
}
}
var delegate:MultiSelectPickerDelegate?
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return multiSelectGroups.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return multiSelectGroups[section].multiSelectOptions.count
}
//MARK: UITableView datasourse function
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
delegate?.didSelectOption(indexPath.row, group: indexPath.section)
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 40))
let label = UILabel(frame: CGRectMake(10, 0, tableView.frame.size.width, 40))
label.font = UIFont.systemFontOfSize(14)
label.text = multiSelectGroups[section].name
label.textColor = UIColor.whiteColor()
view.addSubview(label)
view.backgroundColor = UIColor.MyAppBlue()
return view
}
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier")
if cell == nil{
cell = UITableViewCell(style: .Default, reuseIdentifier: "reuseIdentifier")
}
cell?.textLabel?.text = multiSelectGroups[indexPath.section].multiSelectOptions[indexPath.row].name
return cell!
}
}

I was having same problem. On my table view it was not clicking very last row of my table on the first tap. It highlights it, but didSelectRowAtIndexPath isn't being called. All the other rows work fine. But if I turn the tableview bounce on then it seems to solve the problem
Also try removing Show Selection on Touch in Interface Builder as follows:
Hope it helps

Related

How to detect if a table view cell is tapped in xcode 7

How do I detect if a table view cell is tapped. The guides and tutorial on the web follow the approach of adding a button to the table cell view - prototype cell. This button remains same for all rows and when tapped, returns the index of the row or cell.
I want to do this without the button. How can I invoke
#IBAction
when a cell is tapped and then perform a segue inside the function.
How should I go about it?
I added the following code, but this does not print anything
class MoreViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let moreOption = [
("My Profile"),
("Settings"),
("Logout")
]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationController!.navigationBar.barTintColor = UIColor(red: (48/255.0), green: (187/255.0), blue: (197/255.0), alpha: 1.0);
self.navigationController!.navigationBar.tintColor = UIColor .whiteColor();
self.navigationController!.navigationBar.translucent = false;
self.navigationController!.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : UIColor .whiteColor()]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func logout() {
print("Logout tapped");
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return moreOption.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
let (celloption) = moreOption[indexPath.row];
cell.textLabel!.text = celloption;
cell.textLabel!.textColor = UIColor(red: (74/255.0), green: (74/255.0), blue: (74/255.0), alpha: 1.0);
return cell;
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)
print(cell);
}
}
Why aren't you using UITableViewDelegate method?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
In this method you will get the indexPath of cell tapped and here itself you can open the new controller if you want.
Try This
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedItem = items.objectAtIndex(indexPath.row) as String
print(selectedItem)
}
On the code you are not adding the tableview outlet (or variable if you are building it from code).
You need first to add the tableview outlet to your class and then set the apropiate delegate and datasource for it
for example
//this is connected to your storyboard
//It may have typing errors it is not tested
//at this on the top of your class
#IBOutlet weak var table: UITableView!
//at this on viewdidLoad or viewDidAppear
table.delegate = self
table.datasource = self

Inside Subclassed UITableViewCell Override Func LayoutSubviews Being Called Double

I have a subclass of UITableViewCell that has is having override func layoutSubviews() called twice for each cell. This is creating multiple copies of elements within the cell.
The UITableView returns the proper count of cells and displays the correct number of cells but the layout function resets a handful of properties to nil. Therefore rendering a lot of the data incorrectly.
TableView Inside UIViewController:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userMatches.count // return 2 correctly
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return self.view.bounds.height * 0.20
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: MatchTableViewCell = self.matchTableView.dequeueReusableCellWithIdentifier("matchCell", forIndexPath: indexPath) as! MatchTableViewCell
cell.matchDetails = userMatches[indexPath.row]
cell.userInteractionEnabled = true
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell // creates 2 correctly
}
UITableView Subclass:
override func layoutSubviews() {
super.layoutSubviews()
// runs 4 times
let userHelperIconArray = [userZoom, userTakeTwo, userStopper]
let opponentHelperIconArray = [opponentZoom, opponentTakeTwo, opponentStopper]
layoutHelperInventoryIcons(self, opponentHelperIconArray: opponentHelperIconArray, userHelperIconArray: userHelperIconArray, opponentNameLabel: opponentName)
layoutMiniGameboard(self)
self.layer.borderWidth = 1.0
self.layer.borderColor = UIColor.blackColor().CGColor
print("one")
turnIdentifier(self, matchDetails: matchDetails, opponentNameLabel: opponentName)
}
You should 't be doing this in layoutSubviews anyway. Instead, move the configuration to a separate method, and have your table view data source call that configuration method after dequeing the cell.

Change cell height but not elements in it

I have a prototypes cell that changes height when I touch up inside it; below how I made it:
class SquadreController: UITableViewController
{
var index: NSIndexPath = NSIndexPath()
override func viewDidLoad()
{
super.viewDidLoad()
DataManager.sharedInstance.createCori()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return DataManager.sharedInstance.arrayCori.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
let squadra = DataManager.sharedInstance.arrayCori[indexPath.row]
cell.backgroundColor = UIColor.clearColor()
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
index = indexPath
tableView.beginUpdates()
tableView.endUpdates()
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
if index == indexPath
{
return 176
} else
{
return 88
}
}
}
Ok, it works perfectly. Now I need to put an UIImage in that cell, but I need that image were partially visible like this:
The final effect I would like to realize it's quite similar to this mokeup https://dribbble.com/shots/1293959-LiveSport-App: like the mokeup in my cell there will placed UIImage, labels, views, button.
This is it, if someone could help me with a step by step guide to do this or with some tutorial, I would be grateful!!!
I solved simply with set top, left, right constraints (not bottom) and height constraint to the UIImageView; so the image would not be resized but partially covered by the cell.

SWRevealViewController open tableview when cell selected - Swift

I am using SWRevealViewController, I have three cells like "first" "second" "last". And I have three different tableviews, "firstTableViewController", "secondTableViewController", "lastTableViewController".
I tried to use didSelectRowAtIndexPath, the prepareforsegue. But I couldn't implement multipe segues in didSelectRowAtIndexPath.
Is there a way to do this?
import UIKit
class SideBarTableViewController: UITableViewController {
var MenuArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
MenuArray = ["First","Second","Last"]
var view = UIView(frame: CGRectZero)
self.tableView.tableFooterView = view
self.tableView.backgroundColor = UIColor.whiteColor()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return MenuArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(MenuArray[indexPath.row], forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = MenuArray[indexPath.row]
return cell
}
}
cell identifiers : First, Second, Last
Thanks,
Ok, I found the solution. Followed this tutorial, there is no need to set a segue in code, just kntrl+drag to the view controllers and select "SWRevealViewControllerSeguePushController" ...
http://www.appcoda.com/sidebar-menu-swift/

Swift tableView cell set accessory type

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet
var tableView: UITableView
var items: String[] = ["We", "Heart", "Swift"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "myCell")
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("myCell") as UITableViewCell
cell.textLabel.text = self.items[indexPath.row]
cell.accessoryType = UITableViewCellAccessoryType.DetailDisclosureButton
cell.selectionStyle = UITableViewCellSelectionStyle.Blue
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
return cell
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
}
}
My problem is that the accessoryType and the selectionStyle don't get changed.
The tableView.separatorStyle does get changed as well as the cell.textlabel.text.
How can I fix that?
UITableViewCell.SelectionStyle.blue
The cell has a default background color when selected.
In iOS 7, the selection color is no longer blue. Use
UITableViewCell.SelectionStyle.default instead.
As for the accessoryType, it should work fine as long as you don't change it later somewhere else. Make sure that the table width is correct, otherwise accessory views might be offscreen.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet
var tableView: UITableView
var items: String[] = ["We", "Heart", "Swift"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "myCell")
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("myCell") as UITableViewCell
cell.textLabel.text = self.items[indexPath.row]
cell.selectionStyle = UITableView.CellSelectionStyle.blue
/*
enum UITableViewCellAccessoryType : Int {
case none // don't show any accessory view
case disclosureIndicator // regular chevron. doesn't track
case detailDisclosureButton // info button w/ chevron. tracks
case checkmark // checkmark. doesn't track
case detailButton // info button. tracks
}
*/
// Standard options
cell.accessoryType = UITableViewCell.AccessoryType.none
cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator
cell.accessoryType = UITableViewCell.AccessoryType.detailDisclosureButton
cell.accessoryType = UITableViewCell.AccessoryType.checkmark
cell.accessoryType = UITableViewCell.AccessoryType.detailButton
// Custom view options
cell.accessoryType = UITableViewCell.AccessoryType.none
cell.accessoryView = UIView(frame: CGRectMake(0, 0, 20, 20))
cell.accessoryView.backgroundColor = UIColor.blueColor()
return cell
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected cell #\(indexPath.row)!")
}
}
Note that it isn't a good solution to set separatorStyle of the table each time the cell is requested, instead do it once when the tableView is loaded: at viewDidLoad.
I didn't have any luck setting it in the cellForRowAtIndexPath method, moving it to willDisplayCell fixed the issue with it not showing up.
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.accessoryType = .DisclosureIndicator
}
I would like to share my experience about this, I had the same issue, cell.accessoryType = IUTableViewCellAccessoryType.Checkmark
And I noticed my tableview didn't have constraints, so I added missing constraints then it worked for me
Below will set your accessoryView as an icon named "sentIcon". Just in case!!!
let sentImage = UIImage(named: "sentIcon")
let sentImageView = UIImageView(image: sentImage)
sentImageView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
sentImageView.tintColor = .lightGray
cell.accessoryView = sentImageView