8

This is more or less a continuation of this post: Button in UITableViewCell not responding under ios 7

I am having the same exact issue and have tried every suggestion in the thread. Obviously I don't own that question so I can't edit it to give more info, and thus why I am posting this question now!

Problem:

I have VC nib that I load up that has a tableview in it that I resize based on how many rows are in it. Each row is made from a custom uitableviewcell subclass using a nib file. That class/nib has 4 buttons in it. I can load this code up in iOS 6 or iOS 8 right now and it works perfectly. I don't have a iOS 7 device so I'm bound to the simulator which is at 7.1 (which is the version I'm guess the user that reported this issue was using as well given it was today). Now in the simulator, and the user's phone, I can touch/click everything else on that VC except any of the buttons in the cells. It's as if they had UserInteractionEnabled set to NO, but they don't and neither are any of their parent views (as I'll soon get into).

Tried solutions:

-Completely recreating the nib from scratch both using and not using autolayout

-Calling [self.contentView addSubview:button] in the awakeFromNib of the cell class

-Tried re-adding the buttons to the contentView at runtime with [self.contentView addSubView:button]

-Have ensured four times over that every view in the hierarchy I can find that leads to these buttons have userInteractionEnabled set to YES. (including but not limited to the tableview itself, the cell, the contentView and when I added a "parent view" to the buttons that it was set as well)

-Tried raising all the buttons with a parent view that contains nothing but the buttons

-All buttons are at the top(visually bottom) of the event stack(add and remove are the other two buttons): Hierarchy List

-Have set the table cell selection from single to none.

-I am not overriding layoutSubviews in my cell class

-I can not move any views outside of the Content View as Interface Builder takes them completely out of the cell if I do that.

-I have tried disabling the userInteractionEnabled on just the ContentView at runtime with no change

-I tried putting in the cell creation code of the tableview [cell bringSubviewToFront:cell.button]; for the different buttons to the same result.

Hopefully Helpful Facts:

-I tried setting all of the background colors of all of the views in the hierarchy to different colors so I could visually debug it at runtime... it looked exactly as expected. No overlaps or coverings. (This was limited to only views in the cell)

-Here is all of the settings for the TableView: TableView SS 1 TableView SS 2

-I tried to load this in the new XCode 6 to use the visual debugger but the 7.1 simulator included with it actually ran the code perfectly so I could debug it...

-Here is the dequeueing code in the VC:

NiTGroupTimeCell* cell = (NiTGroupTimeCell*)[tableView dequeueReusableCellWithIdentifier:ident forIndexPath:indexPath];

-Here is the code in the viewDidLoad of the VC to set up the cell nib with the table(it's 2 because this is the from scratch one):

[self.timesTable registerNib:[UINib nibWithNibName:@"NiTGroupTimeCell2" bundle:nil]  forCellReuseIdentifier:@"GroupTime"];

-All connections were made via IB. These are all using IBAction or IBOutlet.

-I have NSLog statements in all button methods to test if they are actually called, but I have also tested with breakpoints. All are never triggered in testing.

-The only TableView delegate or datasource methods implemented are as follows:

-(int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

-As per suggestion I took Revel to it and found that a mystery UILabel and UIImageView were in the view.... but as you can see their frames are all zeros so they shouldn't be getting in the way of anything so back to where we were I'm afraid:

Layers

Hierarchy List from Revel

UILabel frame: UILabel frame

UIImageView frame: UIImageView frame

IIRC I counted this off as a Simulator bug before, but since it's happening on the user's device it must be an actual issue and it's holding up my pipeline so help would be GREATLY appreciated! Thanks in advance!

PS I'm happy to post whatever, but because of all the shifting in debugging I didn't know exactly what people would want to see and I didn't want to overload this post because I knew it was going to be long with everything else.

Community
  • 1
  • 1
Matthew Clark
  • 571
  • 1
  • 9
  • 33
  • are there any uitouchgesturerecognizers on this view? – Roma Jul 31 '14 at 06:09
  • realise it's very small point, but you never know.... you don't need to cast the NiTGroupTimeCell when dequeueReusableCellWithIdeintifier as it will return the cell OK without doing that (NiTGroupTimeCell*) – Jim Tierney Jul 31 '14 at 06:16
  • Roma: No, no UITouchGestureRecognizers. – Matthew Clark Jul 31 '14 at 06:17
  • Jeely: good to know, thanks^^ – Matthew Clark Jul 31 '14 at 06:17
  • Can you post the code that catches the UIButton's action please? Were the UIButton's dragged on to the xib, or did you make them programatically? ....and one final silly question - is the simulator 3.5inch or 4 inch screen that you're using? – Jim Tierney Jul 31 '14 at 06:32
  • The actions were connected via IB. I've tried it with both, but mostly with 4 inch. – Matthew Clark Jul 31 '14 at 06:46
  • Thanks, are the buttons connected via IBAction and have you set breakpoints to see if they are being hit within these -(IBAction)buttonPressed:(id)sender{ methods? - Or are you using didSelectRowAtIndexPath delegate method from the parent view controller class, and if so, are the breakpoints being hit here too? – Jim Tierney Jul 31 '14 at 06:51
  • Jeely, I've appended the answers to your questions to the "Hopefully Helpful Facts" section. Thanks for your continued help! – Matthew Clark Jul 31 '14 at 08:12
  • When I have problems with UI I find `reveal app` to be a lifesaver: http://revealapp.com - Usually just to discover there is a view over the top that I had no idea was there :S – William George Aug 02 '14 at 12:06
  • I've tried that once before, but it's been a very long time. It appears that there is an empty `UILabel` and `UIImageView` higher in the hierarchy that just appeared out of nowhere BUT both of their frames are `(0,0,0,0)` so shouldn't be causing this... still weird though. – Matthew Clark Aug 02 '14 at 23:59
  • are you able to get other control events from those buttons like touch down and touch up? – Jeff Holliday Aug 05 '14 at 16:34
  • "The only TableView delegate methods implemented are as follows:" ... those are datasource methods. Which delegate methods have you implemented? Which object in the responder chain *is* getting the touch? – quellish Aug 05 '14 at 20:09
  • @MatthewClark you never showed any relevant code? – meda Aug 05 '14 at 20:27
  • @JeffHolliday: no events are being received at all it seems. @quellish: Sorry about that, clarified it in the OP, but those are the only delegate or datasource methods I was implementing. I added a `didSelectRowAtIndexPath` for testing and it never fired, nor did `willSelectRowAtIndexPath` however, as I said everything is `userInteractionEnabled` and working fine on every other version of iOS... @meda:I explained that in the OP, what source would you like to see? – Matthew Clark Aug 05 '14 at 20:33
  • @MatthewClark its almost time to post the entire codebase to your github account ;) – William George Aug 05 '14 at 21:09

9 Answers9

3

So apparently the issue was these lines of code(in diff format from my git diff output):

--(int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
+-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

and

--(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
+-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

so yeah... seems that in iOS7+ if you have the "old" output types for these datasource methods it'll look fine but bork your tableview functionally... good times, but hey it's fixed now^^ hopefully this helps others.

Matthew Clark
  • 571
  • 1
  • 9
  • 33
  • Wow?!? You're saying that simply changing the return value of those UITableViewDataSource methods fixed it? – race_carr Aug 07 '14 at 16:39
  • I couldn't believe it either..but I was being fairly methodical in my testing of it so I'm pretty positive that was the solution. I found it by looking through the compile warnings(I know I should always do that but it's hard when they tend to be a spam of "cyclic blocks" and "casts to a lower precision" warnings) where it was warning about how it could find the method to override and then said, for example "(NSInteger) vs. (int)" return or something like that. Didn't think it would help much, but didn't see where it would hurt so I tried it anyway and tada. Thanks again for your help!^^ – Matthew Clark Aug 07 '14 at 20:40
1

I would suspect that there's an issue with your custom UITableViewCell subclass, NiTGroupTimeCell, or with the IBAction connections from the nib to the tableViewCell subclass.
I also wonder about the extra empty UILabel and UIImageView. They sound like the default properties declared in UITableViewCell.h, UIImageView *imageView and UILabel *textLabel. The fact that they're getting instantiated (and aren't nil) could be a clue as to the weird, unexpected behavior you're seeing.
Do you have IBOutlets to the UIButtons? What about changing properties (in code) for the buttons (such as background color) to make sure you actually are retaining them in the NiTGroupTimeCell.

race_carr
  • 1,387
  • 12
  • 21
  • I have `IBOutlets` for all 4 and set the background color of all to black and all reflect that at runtime. Is there a different test that may give us more information? – Matthew Clark Aug 04 '14 at 03:41
  • Are there any other elements in the cell that are touch targets? Does the UITableViewCell highlight and/or allow selection thru delegate methods like `- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath`? – race_carr Aug 04 '14 at 13:10
  • No, and no. Just the 4 buttons. – Matthew Clark Aug 04 '14 at 19:48
  • How about implementing that UITableView delegate method I mentioned with a simple NSLog()? – race_carr Aug 04 '14 at 20:19
  • Interesting..I changed selection on the table from "None" to "Single" and implemented `-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath` but it's never triggered either..so I tried `-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath` so see if it was even getting there, but that doesn't trigger either..Double and triple checked Reveal to verify that there aren't any views covering it. Also made sure the delegate was set on table. As you can see above the `userInteractionEnabled` is on..I'm at a lose. – Matthew Clark Aug 04 '14 at 23:43
  • It's almost as if [[UIApplication sharedApplication] beginIgnoringInteractionEvents] has been called and the app is just ignoring touches. Are there enough cells in the tableView for it to scroll? – race_carr Aug 06 '14 at 13:42
  • No, I actually have the scrolling disabled. There are actually 3 buttons and a textfield not in the table and all of them behave as expected... and only happens on iOS7.1(maybe 7.0 as well, but I could have sworn I tested it on 7.0 and it worked) ... it's really weird... – Matthew Clark Aug 07 '14 at 03:59
  • I'd be curious to know if the tableView responds to ANY touches. That's why I asked about scrolling. Obviously the view can respond to touches, since you've mentioned the other buttons and textField that work. – race_carr Aug 07 '14 at 04:11
  • I tried re-enabling scrolling and it wouldn't scroll... I had it disabled in part because the table is embedded in a scrollview, but I'm pretty sure that it should still scroll if scrolling is enabled... may be wrong... Anyways, any idea why a tableview wouldn't receive any touch events even if it's and it's parent's(working scrollview) `userInteractionEnabled` are switched on and it's not covered by another view? – Matthew Clark Aug 07 '14 at 04:53
  • So you didn't get it there, but you were the closest, so enjoy^^ – Matthew Clark Aug 07 '14 at 11:04
  • Thanks, @MatthewClark! The tableView doesn't happen to be embedded in a UIScrollView? Are you using AutoLayout? That's another wildcard that might be causing unexpected behavior? – race_carr Aug 07 '14 at 12:47
  • I've tried it both with and without auto-layout, but regradless it's been embedded in a UIScrollView. – Matthew Clark Aug 07 '14 at 20:25
0

You're saying that you tried [self.contentView addSubview:button] but your button in your first image is inside a view inside contentView. Try linking an IBOutlet to that view, then try [nameOfView addSubview];

iOSAaronDavid
  • 140
  • 15
0

Throwing a wild guess as it looks like you have covered pretty much everything else.

You said:

I load up that has a tableview in it that I resize based on how many rows are in it

And you posted a screen shot saying the clip subviews is off on the UITableView

Are you setting the frame of the tableview incorrectly but its showing the cells anyway due the the subviews not being clipped?

Load up reveal again and check the height of the UITableView

William George
  • 6,735
  • 3
  • 31
  • 39
  • Really good thought, but no the height of the `UITableView` is 45 for a single row, as it should be. Also, just to be sure I turned `Clip Subviews` on to make sure if that does pop up it'll be obvious. Thanks for the try!^^ – Matthew Clark Aug 05 '14 at 02:10
  • Dang, is the app in the App Store, mind posting a link? – William George Aug 05 '14 at 06:08
  • Long long story short, no it's not in the app store yet.^^; We were about to hand it off when this "edge case" was found. – Matthew Clark Aug 07 '14 at 04:00
0

Not sure if it is the case here. But if you name the custom cell outlets imageView, textLabel or any of the "built-in" UITableViewCell's properties you will get weird results and behavior.

Rivera
  • 10,792
  • 3
  • 58
  • 102
0

You need to check couple of things:

  1. Make sure all the parent views of the button have User Interaction enabled.
  2. Check AutoSizing in the size inspector and make sure the button lies inside the view so it could receive touch events otherwise touch events will get ignore. You can verify it by changing the colour of the view. Changing colour or NSLog the frame of button and parent views will help you to troubleshoot if this is the problem.
  3. Try to make things simpler and don't addSubView programmatically, if designing from IB.
  4. Make sure some component is not overlapping the button with a clearColor background color.
NeverHopeless
  • 11,077
  • 4
  • 35
  • 56
  • 1. All have been checked 2. I have verified it is both visible and not covered via coloring and Reveal app. 3. I suppose I didn't make it clear in the original post but even though I did try bot `addSubview` and `bringViewToFront` the current version is purely using IB. 4. answered in 2 – Matthew Clark Aug 05 '14 at 06:58
0

What worked for me is this:

self.contentView.userInteractionEnabled = NO;

I called this after loading my custom cell from nib / storyboard. Without the userinteractionEnabled set to NO, my buttons haven't been responding to touches somehow. My contentView has received all touches and did not forward them to my buttons.

I've seen code where

[cell bringSubviewToFront:button]

has been used as a workaround, for me it did not solve the issue.

Alexander
  • 7,178
  • 8
  • 45
  • 75
0

I had a simillar issue, while adding Custom Acions based on Guestures.

I was adding Action Button on runtime in Inherited class of UITableViewCell The bahaviour was if I add buttons outside the visible rect, after animating buttons inside, I was unable to click / tap. But in My Case I was able to Tap / Click if buttons were added in visible rect.

What Worked for me, I added those buttons in View instead of ContentView of UITableViewCell, then animated only Content View. You may try somthing simillar

-- Vishal

Vishal Kardode
  • 961
  • 2
  • 8
  • 25
0

You've said that there are no TouchRecognizers(TapRecognizers?), but I think you should double-check that, and look not only for touch recognizers but for any recognizers in controller that uses that cell,even added to self.view/tableView. I was recently trying to find out why cells don't select(delegate method wasn't called) only to find out that I've added 2 gesture recognizers(in code, those were necessary for other things, but I had to do that in other way) that would prevent cell selection.

Also the sign of it may be that if you hold button long enough(put breakpoint there so you can make it easier), action will fire.

Timur Kuchkarov
  • 1,155
  • 7
  • 21