subclassing a UITableViewCell with UIImageView in it - objective-c

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)

Related

scrolling a scrollView inside of a textView delegate

I have a UIScrollView and contextView. I add UITextViews to it and set the delegate to self so that I can use the textViewShouldBeginEditing method. The textViewShouldBeginEditing is inside the same ViewController.m file, so the VC should be the delegate.
The textViewShouldBeginEditing method gets called and I want to check if the keyboard is blocking the textView and scroll it up if it's being blocked.
I want to call:
[scrollView setContentOffset:CGPointMake(x, y) animated:YES];
However scrollView is not seen in textViewShouldBeginEditing.
I've seen where KVO can be used, but I want to use the delegate methods.
How can I gain access to the scrollView that the textView is on?
You can use IQKeyboardManager. Just drag and drop library to your project and eveerything will managage itself. here is the github link for that. IQKeyboardManager. Hope this will help you.

touchesBegan in UIView not being called

I know that this question must have been answered plenty of times already, but I have no idea why the touchesBegan: is not called in my UIView.
Before I added it in my app, I made a trial project to do some tests. What I did was subclass a UIView where the touchesBegan: is implemented and add this as a subview of another view. The superview has a button which shows the subclassed UIView once clicked. Everything works as expected.
However, when I did the same thing in my existing app, the touchesBegan: method, as well as the touchesMoved:, were never called. Can anyone explain what could be preventing the methods from being called?
I just found the answer to this. I realised that the superview of the UIView has the userInteraction set to disabled (which is the default value). So when I enabled the userInteraction of the superview, the touches are now recognised.
In my case background = UIColor.clearColor() was the reason why touchesBegan was not called. Its obviously not called on transparent elements.
I was struggling on this problem for a while... and i figure it out. I think that the touchesBegan override function listen on the main view: the first one on the storyboard tree of the ViewController! I would love to post an image of my storyboard to be more clear, but i can't! ;)
Anyway, IF you have subviews, they may covers the main view... in this manner the touch wont "reach" the main view.
To avoid this you'll have to set the Background property in the Attribute Inspector to Default for ALL THE SUBVIEWS. In this way the background will be transparent and the touch will be able to reach the main view.
If you don't want to set the background to transparent there is something you can do:
-Add an outlet of your last view (with background set)
-Add a tap gesture recognizer to it
-Handle the tap disposing the keyboard
ES.
In properties:
//The last view's outlet
#IBOutlet weak var ContainerView: UIView!
In viewDidLoad():
let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
self.ContainerView.addGestureRecognizer(tap)
Outside:
func handleTap(recognizer: UITapGestureRecognizer){
self.view.endEditing(true)
}

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

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.

UIButton as part of UITableViewCell subview - make it work

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).