UIButton as part of UITableViewCell subview - make it work - objective-c

I'm having some class which is a subclass of UITableViewController.
on one of the TableView's cell I'm adding a view that holds a UIButton as subview
(i.e. [someParentView addsubview:button])
I'm adding the view to cell like this:
[cell.contentView addSubview:someParentView]
I've set the UserInteractionEnabled both for the button and for the view holding it ("someParentView") to YES
but still when I tap it, nothing seems to be happening.
any idea?
Thanks
What i want to accomplish in short: i want to make a tableview that shows some views.
each view contains some subviews, and in one of those cases there is a uibutton as a subview.
i want to have this button to trigger event by user's tap, as any other uibutton, so some method will be launched.
to do that, i made a class which subclasses UITableViewController, and for each cell i added a view using [cell.contentView someView], as i wrote. i disabled selection from all using the [self.tableview setAllowSelection:NO] and for each sell made selection style as NONE.
as said, i also set the view and the uibutton UserInteractionEnabled property to YES.
anything i'm missing?

Been solved!
I have used the method:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
of UIView class in my subclass and returned the button as the returned object.
(of course, needed to test point if in button area).

Related

How do I determine the identity of a UITableView within a Storyboard

I have created a TableView within the Storyboard. I don't want to control-drag links between this and files as programmatically, this is easier to maintain.
However, I don't know how I can determine what the identity of the TableView is within the Scene.
Is there a way of naming this, or somehow determining this sop that I can dynamically change the behaviour of it?
In fact, this sort of applies to everything in the Storyboard. I don't know how to name anything.
Use tag, under the View category:
Every view (control) has it. You can use viewWithTag method of UIView to get the control you need, like this:
UIButton *button = (UIButton *)[self.view viewWithTag:1]
If you look in your storyboard, when selecting a view controller there is a screen like this in the "Identity inspector" tab:
After assigning a storyboard ID to your view controller and activate the "Use Storyboard ID" option, you can instantiate it programatically with:
ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"MyViewControllerID"];
[self presentViewController:vc animated:YES completion:nil];

How to detect a tap gesture in subviews

Quick question: how do i detect if a tap gesture recognizer is within a subview of the view it is added to? Eg. if i click on an object such as a square that has been added as a subview to a background which a tap gesture recognizer has been added to, how do I detect that it has been tapped?
You can grab the point of the tap off the gesture recognizer when your handler method is called respective to any view you wish using -locationInView:. Then, use the following method on UIView: - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event to get a reference to the actual sub view that was tapped remembering that the point you pass in is in the same coordinate space as the view.
Some code to get you started:
CGPoint point = [tapGestureRecognizer locationInView:parentView];
UIView *tappedView = [parentView hitTest:point withEvent:nil];
For hit testing to work the view needs to have the userInteractionEnabled property set to YES. Many views, such as UILabels have this set to NO by default. So prior to the above:
self.subviewOfInterest.userInteractionEnabled = YES;
maybe you should set as:
subviews.userInteractionEnabled = YES;
good luck!
you can use the requireGestureRecognizerToFail: to recognize the tap on subview please refer this code

subclassing a UITableViewCell with UIImageView in it

I have subclassed a UITableViewCell and inside I have a UIImageView, the problem is that when I tap on the UIImageView, I wanted to do something, but what happens now is that it calls the didSelectRowAtIndexPath. How do I prevent this? Also, should I just add a tap gesture recognizer to the UIImageView to perform some action I want?
Can you use a UIButton with your image instead of a UIImageView? UIButton has all the UIControl functionality.
I'm trying to remember if that's enough to avoid didSelectRowAtIndexPath and I don't remember though I think it is. Do you still want the row to be selectable by tapping outside the image? If not, you can just return NO to canSelectRowAtIndexPath.
Yes simply add a UITapGestureRecognizer on the UIImageView is the way to go.
Don't forget to set userInteractionEnabled to YES on your UIImageView too.
Then, when you will tap on your UIImageView, the touch event will be captured by its UITapGestureRecognizer and won't be transmitted to the cell, so the method associated with your UITapGestureRecognizer will be called but the tableView:didSelectCellAtIndexPath: delegate method won't. (This latter delegate method will only be called if the touch event is not captured by a subview of your cell before)

how to detect number of touches on the uiview in iphone sdk

in my app, when the user touches on the view ,i am showing an UIImageView there and i drag and
drop the image from another UIImageView to that touched UIImageView.
But the problem is that, only the recent touched UIImageView is activated. i mean ,when i
click 3 times then shows 3 UIImageViews but only the last is activated and accept the another
image.
How can i make all touched UIImageViews are activated .. Any body help on this..
Thanks in advance.
You should read Apples documentation on the responder chain and event handling. The key UIView method here is
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
This method traverses the view hierarchy by sending the
pointInside:withEvent: message to each subview to determine which
subview should receive a touch event. If pointInside:withEvent:
returns YES, then the subview’s hierarchy is traversed; otherwise, its
branch of the view hierarchy is ignored. You rarely need to call this
method yourself, but you might override it to hide touch events from
subviews.
You should try this:
Where there is your UIView (Or a view):
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapped:)];
tapGesture.numberOfTapsRequired = 1;//number of tap
[view addGestureRecognizer:tapGesture];
The selector:
-(void)tapped:(UITapGestureRecognizer *)sender {
NSLog(#"Pressed");
}

How to make a custom tableView cell accessory

I have not yet found any really good examples on how to do this. There is an image that I want to use as the accessory button and when I put it in and click on it doesn't work. So it looks correct but doesn't work...
Here is my code:
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
cell.accessoryView = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"TableView_Green_Disclosure.png"]];
So how do I get my UIImageView to call accessoryButtonTappedForRowWithIndexPath whenever it is tapped?
A thorough reading of accessoryView and accessoryType would reveal that they are mutually exclusive ways to customize a cell.
Setting the accessoryType will cause the table view delegate method to be called when it is tapped.
Setting the accessoryView will ignore the setting of accessoryType and give you something to display. If you want to receive a callback from the custom view you've put in place, it should be a control that is wired up to do so. (Or any view with a gesture recognizer.)
If you use a button, and set its action to accessoryTapped:, you will receive the button as the "sender" argument. You can walk up the view hierarchy until you find a table view cell, and then ask your table view what the indexPath of that cell is. This will then get you an index into your model objects and you be able to act on it appropriately.
Alternate to the button, you can enable interaction on the UIImageView above, and add a gesture recognizer to it.
To make the button actually do something, you'll need to implement - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath from UITableViewDelegate.
When an accessory button is tapped in a row, this method will be called and you'll have the chance to act appropriately using the passed in index path to determine which row's accessory was tapped.
Check the blog post hdr->cmdline for creating custom accessory view for UITableView.
The author used UIButton objects with images for custom accessory view.
To make use of the accessoryView - you would need to set the cell's accessoryType to UITableViewCellAccessoryNone deposit a UIButton (with associated image) into the cell and then wire it up to receive user touches. You might use something like the code below as the IBAction response to the cell's UIButton being touched:
- (IBAction) accessoryButtonPressed:(id) sender
{
NSUInteger pathInts[] = { 0,0 };
pathInts[1] = self.currentselectedrow; // ivar set when tableview row last selected
NSIndexPath* indexPath = [NSIndexPath indexPathWithIndexes:pathInts length:2];
[self tableView:mytableview accessoryButtonTappedForRowWithIndexPath:indexPath];
}
The UIButton would be wired to execute this glue code by way of a line inside your tableview's "cellForRowAtIndexPath:" function
[thecell setButtonTarget:self action:#selector(accessoryButtonPressed:)];
One thing I noticed is that the UIButton seems to want a 'swipe right' versus a simple 'tap' touch in order to trigger the event - but it could be my beta iOS that's the problem. Note that I had added a UIButton* object named 'cell_accessoryButton' to the Custom Cell source.
In the cell's source you'd support the 'setButtonTarget' call with code like this:
- (void) setButtonTarget:(MyViewController*)inTarget action:(SEL) inAction
{
[self.cell_accessoryButton addTarget: inTarget
action: (SEL) inAction
forControlEvents: UIControlEventTouchUpInside];
}
It's so much easier to just use the accessoryType reference and let iOS do the heavy lifting - but, if you want a custom graphic, etc - this is another path that works.