Custom UITableViewCell, button in cell not working - ios

I have a UITableViewController where I'm working with a custom UITableViewCell. The cell contains an image, labels and buttons. Everything is working as expected except of the buttons. When pressing the button, nothing happens. Only the cell gets selected.
I made a connection in IB from the button to my custom TweetTableViewCell class.
#property (weak, nonatomic) IBOutlet UIButton *cellFollowButton;
- (IBAction)followButtonTappedonCell:(id)sender;
I'm writing some text to the console in my followButtonTappedonCell action. But when pressing the button, nothing happens. It seems to me that some view consumes the tap before it arrives to the button. To make it more confusing... When I add a button in may UITableViewController programatically like this:
[cell.cellFollowButton addTarget:self action:#selector(customActionPressed) forControlEvents:UIControlEventTouchDown];
[cell addSubview:cell.cellFollowButton];
...it just works.
I read in other articles that disabling "User Interaction Enabled" solved similar problems, but it doesn't in my case.
I'm sure that many others must have run into this problem when using buttons in UITableViewCells. Any help is highly appreciated.
I'm using Xcode 5 for iOS 7.

If your cell is in a nib, make sure the root object is a UITableViewCell and NOT a UIView

I would recommend you to go through this link. It has clear description of your problem. However, I've tried to extract needed info.
Many types of events rely on a responder chain for event delivery. The responder chain is a series of linked responder objects. It starts with the first responder and ends with the application object. If the first responder cannot handle an event, it forwards the event to the next responder in the responder chain.
A responder object is an object that can respond to and handle events. The UIResponder class is the base class for all responder objects, and it defines the programmatic interface not only for event handling but also for common responder behavior. Instances of the UIApplication, UIViewController, and UIView classes are responders, which means that all views and most key controller objects are responders.
In your Case, when you are writing event methods in your customTableViewCell class, your methods are not being called. this is because, TableViewCell is not participating in Responder chain.
next thing is, check whether "User Interaction is enabled " or not for your Cell. You can find it under View section of "Attribute inspector".

Related

iOS Accessibility - control which UI object gets the focus

I'm having trouble identifying why a UIButton ( specifically a UIBarButtonItem, the menu button in my case) gets the accessibility focus when a UIViewController changes.
The problem is it "cuts" the announcement being read and takes the focus at no need.
So my questions:
How do I find "who" is giving a UI object an accessibility focus. (I tried to override the becomeFirstResponder - it never gets called).
How do I select, programmatically, which UI object gets the accessibility focus now.
Thanks !
To select which object becomes first responder, you can simply call
[becomeFirstResponder()][1]
on the UIResponder object you want to be the focus.

Touch Down firing in a weird way

I'm adding a touch down action to a uitextfield (actually it's a subclass, but I think that might not be important). I created a simple view controller and added this textbox to it, and wired up the event to println("Hello").
When I quickly tap the item (both in simulator, and on my phone) it works perfectly and says hello!
I then created a UITableViewController subclass, and in one of the static cells I added the same textbox.
In this case, when I quickly tap the textbox nothing happens! When I actually hold down the mouse or my finger for about 1/2 a second, it works. But not if I quickly tap it.
This is different from the previous textbox, which always works perfectly no matter how fast I tap it.
Are there some problems with different events being intercepted ors something of that sort?
I even went so far as to add a tap gesture recognizer to both the table cell, and the textbox, but neither work unless I hold it down (the table cell action won't even fire unless I click off the textbox and into the cell proper, of course).
Thanks so much this is very strange.
UIButton not showing highlight on tap in iOS7
and
iOS - Delayed "Touch Down" event for UIButton in UITableViewCell
have a lot of information about this. Apparently there is a delay for uitableviewcells that can be avoided by taking some of the approaches above.
I'll post the solution that works for me once I work on it. thanks!
EDIT OP DID DELIVER!! (lol sorry)
in IOS8, the idea is that table cells no longer have the uiscrollview that would basically delay the touching, so what you can do instead is something like this in your page did load:
for subview in self.tableView.subviews as [UIView]
{
if subview is UIScrollView
{
let scroll = subview as UIScrollView
scroll.delaysContentTouches = false
break
}
}
So see how we're iterating over self.tableview's subviews, and anytime we hit a scrollview set delaysContentTouches to false. This worked for me on both the simulator and on my phone.

What are the "First Responder" and "Exit" boxes purpose in the storyboard editor?

In the XCode IDE, at the bottom of the view controller in the MainStoryboard editor, are two boxes: First Responder, and Exit.
I know what a firstResponder is programatically within the code, but in the storyboard editor, I can't seem to do anything useful by it.
Am I able to use the first responder in this area to somehow set the first responder of the view? I'd like the first textfield to be active on load and I have tried right+click and dragging to no avail. I know I can set it programatically in the viewDidLoad method, but is there some way of doing it here?
And what is the green Exit for?
There are no good answer for this question, so I am posting my answer:
From here:
Note: You probably won’t be using the First Responder very much. This is a proxy object that refers to whatever object has first responder status at any given time. It was also present in your nibs and you probably never had a need to use it then either. As an example, you can hook up the Touch Up Inside event from a button to First Responder’s cut: selector. If at some point a text field has input focus then you can press that button to make the text field, which is now the first responder, cut its text to the pasteboard.
Edit:
1) First Responder is very useful if you are using text fields with keyboard notifications. I use it to make keyboard disappear, make an outlet to variable currentFirstResponder of your class, and in viewWillDisappear:
[self.currentFirstResponder resignFirstResponder];
2) You can read about unwind segues ("Exit" box) here
I've never used it and probably never will but you can assign an object to be the first in line to receive the events from the UI.
I suppose you could be creating a UIView subclass and add it in to a UIViewController but you actually want some other object to receive and process the events other than the UIViewController you are adding it to.
I found this link which kind of explains it a bit better.
First Responder: The First Responder icon stands for the object that the user is currently interacting with. When a user works with an iOS application, multiple objects could potentially respond to the various gestures or keystrokes that the user creates. The first responder is the object currently in control and interacting with the user. A text field that the user is typing into, for example, would be the first responder until the user moves to another field or control.
Exit: The Exit icon serves a very specific purpose that will come into play only in multiscene applications. When you are creating an app that moves the user between a series of screens, the Exit icon provides a visual means of jumping back to a previous screen. If you have built five scenes that link from one to another and you want to quickly return to the first scene from the fifth, you’ll link from the fifth scene to the first scene’s Exit icon.
More here
You don't see this very often, where a deleted answer is actually correct, and the comment (likely influencing its deletion) on it is totally wrong! I'll try and improve on it.
Usually the IBAction you want to hook up to a button is in the view controller containing the button. However if the IBAction is in a different controller, e.g. a parent controller then drag from the button to the First Responder object and you are able to select the IBAction in the parent controller!
As the hidden answer states, how this is implemented is the action is sent to nil, which has the effect of the responder chain (i.e. view hierarchy) being searched for the action, as follows:
[UIApplication.sharedApplication sendAction:#selector(nextObject:) to:nil from:self forEvent:nil];
An example is a custom UITableViewCell. Add a UIButton to the cell but you want the action to go up to a View Controller that has an embed segue to a UITableViewController. Drag the touch up instead action to the First Responder and select the action in the container view controller. In the action to find the indexPath simply loop the visibleCells and check if the sender is isDescendantOfView:
- (IBAction)cellButtonTapped:(id)sender{
for(UITableViewCell *cell in self.tableViewController.tableView.visibleCells){
if([sender isDescendantOfView:cell]){
NSIndexPath *indexPath = [self.tableViewController.tableView indexPathForCell:cell];
NSLog(#"tapped %#", indexPath);
}
}
}
Another example could be a reload button: say your first view controller shows an downloaded item with an IBAction to reload it to get the latest data, then your child controller shows some detail, but you also want them to be able to reload the main item from within the detail, just add a button in the detail and drag its action to First Responder and select the reload IBAction in the parent controller. This allows you to hook up buttons to parent actions with no additional code like delegate methods!
For this to work the action needs to be in the responder chain hierarchy or it won't be found, you can read how the chain is built up in the docs. Also note if called from code the view needs to have appeared, viewWillAppear is too soon.

Using a UIView as a button

I'm trying to use a UIView I've created in Storyboard as a button. I assumed it would be possible to use a UIButton, setting the type to custom. However I was unable to add subviews to a custom UIButton in Storyboard.
As such I've just spent the last hour reinventing the wheel by making my own custom gesture recoginizers to reimplement button functionality.
Surely this isn't the best way of doing it though, so my question - to more experienced iOS developers than myself - is what is the best way to make a custom button?
To be clear it needs to:
Use the UIView I've created as it's hittable area.
Be able to show a
different state depending on whether is currently highlighted or not
(i.e. touch down).
Perform some action when actually tapped.
Thank you for your help.
You can use a UIButton, set the type to custom, and then programmatically add your subviews...
Change your UIView into a UIControl in the storyboard. Then use the method [controlViewName addTarget:self action:#selector(*click handler method*) forControlEvents:UIControlEventTouchDown];. click handler method is a placeholder for the method name of your handler. Use this method except change out the UIControlEventTouchDown for UIControlEventTouchInside and UIControlEventTouchDragExit to call a method when the user finishes their click and drags their finger out of the view respectively. I used this for something I'm working on now and it works great.
In Touch down you will want to: highlight all subviews
In Touch up inside you will want to: unhighlight all subviews and perform segue or do whatever the button is supposed to do
In Touch Drag Exit you will want to: unhighlight all subviews
See second answer by LiCheng in this similiar SO post.
Subclass UIControl instead. You can add subviews to it and it can respond to actions
Why are you implementing your own GestureRecognizer? I recommend using the UIView so you can add subviews in the interface builder and adding a UITapGestureRecognizer. You can even do this graphically since you don't care about IOS4 support.

UITextField is not responding

I'm experiencing some problems with UITextField inside a UITableViewCell.
Things are working well until I open the iOS media player, watch a short movie and going back to my view.
Then, I'm trying to click on the UITextField, but nothing happens and it does not responds to my clicks.
In the same screen (it's a UITableView), I have a switch button (in another row), which is working fine after switching views.
My view is implementing the UITextFieldDelegate protocol and textFieldShouldReturn in particular.
My implementation of textFieldShouldReturn is a simple call to : [textField resingFirstResponder]
I'll appriciate any thoughts or ideas why it happens and how to solve it.
Thanks!
koby
I had this same problem, what fixed it for me was to make sure to return the correct height for the table view cell. Check your heightForRowAtIndexPath function - even though you can see all the objects in your cell they may be outside of a clickable/tappable area.

Resources