How to tell when a user taps in a UITableViewCell? - objective-c

I'm working on an iOS app where I have UIWebviews inside UITableViewCells. The UIWebViews take up about 50% of the cell and the rest of the cell is blank. I need to be able to respond when a user taps in one of my cells. I've tried implementing the - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method, but this only responds when a user taps in a part of my cell that does NOT contain a uiwebview. Is there any way in which I can respond to a tap regardless of where in my cell the user taped?

you can set userInteractionEnabled property of your UIWebView to NO, but in this case you will not be able to scroll it..

Your design is definitely bad: Apple explicitly says in the UIWebView class reference, that you should not add UIWebViews to table cells. Also, as the web view internally manages an UIScrollView, which captures all the touches. So the only way to do what you want is to subclass UIWebView and override the touch management methods. This is also not advisable, as UIWebView is one of the few classes which are not to be subclassed according to Apple.
You have to seriously reconsider your design pattern.

First, do this to your webview. Then, call the tableView's didSelectRowAtIndexPath method when a tap is registered. Kind of a pain, but the only way I can think of. This will allow the user to interact with the webview in a completely normal way, but sends lets the table know which cell is being interacted with. If that's not what you want, the other answers should work.

Try attaching a UITapGestureRecognizer to your cell.

Related

Use single UITableViewCell subclass across multiple UIViewControllers

So I have this UITableViewCell subclass that has some really complicated logics in it - it triggers some actions in UIViewController it's actually attached to. Of course the cell is not aware of its UIViewController but I still navigate to it like this:
UITabBarController *tabVC = (UITabBarController *)appDelegate.rootVC.centerPanel;
SGFirstTabViewController *firstTab1 = [tabVC.viewControllers firstObject];
[firstTab1 reloadCell:self];
The thing is now that I want to use the same subclass of UITableViewCell around about 5 different UIViewControllers.
What's the best way to do this? I will almost never know what is the UITableViewCell's VC is and I simply can't create 5 different cell subclasses with the same code over and over. What's the best way around it?
I think there is perhaps some misunderstanding in the role of the cell in the model-view-controller programming pattern.
The cell should not reload itself but it should be told to reload by the view controller that controls it. The reload code in the cell can stay the same.
So, rather than the cell having to find out which one its view controller is, have the view controller listen to the cell action (e.g. via delegate methods) and fill it with the appropriate reload data as directed.

Forward horizontal swipe events on UITableView to parent view

I have a UITableView that I want to have respond to taps and vertical swipes, but still have something like userInteractionEnabled = NO for horizontal swipes. By that I mean, it would not handle touches and pass the touch event back to its superview.
Things I've tried that didn't work:
returning NO in - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
Overriding touchesBegan/touchesMoved/touchesEnded and passing the event to the next responder
Adding gesture recognizers for horizontal swipes and setting cancelsTouchesInView to YES
I've been trying to fix this on and off for several weeks, so any help is greatly appreciated!
better you can subview empty view for tableview.view color should be
empty and add gesture to that view.if gesture direction is
vertical.scroll tableview
Did you try just adding a horizontal swipe gesture recognizer to your table view's parent view? Also turn off horizontal scrolling on your table view. (set alwaysBounceHorizontal=NO)
Disabling user's interaction for each table view cell should help.
I suggest doing it in cellForRowAtIndexPath method.
The answer to this question is not simple, because UITableView manages a lot of touches, and this touches are managed by different components.
So, to give you a correct and working answer, you have to explain:
what kind of swipes you want to disable (left-to-right, right-to-left)
where (on the empty table view, on the cell)
what happens now when you do this swipe (the cell goes in edit mode, a navigation controller goes to the previous page ecc....)
For example: the swipe-to-delete on a UITableViewCell can't be avoided by overriding touchesBegan:withEvent, because the touch is received by the internal content view (UITableViewCellContentView private class, so you can't subclass and override touchesBegan:withEvent).
But this is not necessary, because you can disable this behavior adding this method to UITableViewController:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
When you disable the editing (for example) the cell and the table view are no more capable of managing the touch, so the touch is forwarded to the next responder in the chain.
This is only one example, you must explain all the cases that are giving you undesider behavior to let us help you more.
Last suggestions:
At this Page you will find a very good and interesting explanation on how the hit test end event handling process works.
I'll update the answer with more specific information when you'll add more details.
Regards
Fabio

UICollectionView responding while being scrolled?

I have a UICollectionView filled with some cells, and i implemented the method - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
This works like a charm, but it doesn't work while it is scrolling. It is a problem since the scrolling is very sensitive, and thus when i mean to push a cell and call the method, i end up scrolling with no result.
So i was wondering how to counter this and came up with this:
Can i simply set the method to respond while it is scrolling?
If not - Can i simply make it so scrolling ONLY happens if you use for example 2 fingers? to seperate the 2 actions more.
Thanks on advance
The selection of a UICollectionViewCell happens when you tap it. A tap should be short and at one place. If you scroll instead, you're probably not tapping right. If this is the case, it would also happen while using built-in apps like Mail.
The UICollectionView uses a UITapGestureRecognizer to recognize selection of cells. This gesture recognizer doesn't allow specifics settings that might help you out in this case.
You might be able to change the UIPanGestureRecognizer to need 2 fingers, but you should really think about if that's what you want. You'd better use it the way Apple means it to be used, users are used to that.
That said, here's the documentation page on collection view's gesture support:
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/IncorporatingGestureSupport/IncorporatingGestureSupport.html
You might be able to use this to change the minimumNumberOfTouches property of the internally used UIPanGestureRecognizer. But again, I don't think you should.

UITableView in a UIScrollView - How to make the view scroll, but not the TableView in itself?

Imagine, there is a UIViewController with a UIScrollView in it. At the top of the view there is an UIImageView, some UILabels and other things. Furthermore, there is a UITableView which content is Dynamic Prototypes. I attach a picture to make it clear:
I haven't got a static amount of cells in the UITableView so it could be scrollable. My problem is the following: the UITableView scrolls in itself but I want to scroll the whole View. What is the best possibility to do that?
Possible solutions I've founded today
1) The first thing is: I create a UITableViewController and declare a header section in which I include all my labels, images etc. programmatically (I would love to use the interface builder for that...)
2) Another solution is to calculate the height of the view. I tried the best to do it like this way - but: without success. If this is the best way to do that: Can anybody give an example?
I would ditch the UIScrollView and just use a UITableView. You can add a UIView object as the tableHeaderView of the UITableView just by dragging it in in Interface Builder. Now since everything is part of the UITableView hierarchy, everything will scroll together as expected.
You could also try setting delaysContentTouches to NO on your scrollView. Depending on your setup, this may make the scroll view respond to the touch first instead of the table view.
From Apples UIScrollView Docs:
delaysContentTouches
A Boolean value that determines whether the scroll view delays the
handling of touch-down gestures.
#property(nonatomic) BOOL delaysContentTouches
Discussion
If the value of this property is YES, the scroll view delays handling
the touch-down gesture until it can determine if scrolling is the
intent. If the value is NO , the scroll view immediately calls
touchesShouldBegin:withEvent:inContentView:. The default
value is YES.
You'll have to (as you've mentioned) add the UIView containing the image and buttons to the actual UITableView. Embedding it in the scroll view will produce the undesired behavior that you're seeing.
I would recommend returning the UIView as the header view for the first section of your table view. You can do this by implementing the UITableViewDelegate method:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
If you maintain an IBOutlet to the view containing your image/labels, you can return it here.
this is same demo i hope its helps you from iphone sorce code library
http://developer.apple.com/library/ios/#samplecode/iPhoneCoreDataRecipes/Introduction/Intro.html
thank you

how to write inside a cell of UITableView

How do I write inside a cell of UITableView using TouchesBegan and TouchesEnd methods?
A UITableView scrolls and so cells move. What you are talking about would pretty much prohibit a table from being able to scroll. Of course you could have a static table or some other table which never scrolls and so you think that's ok.
In that case, handling touch events in a UITableViewCell is the same as handling the touch events in any other UIView. You could use a add a UIGestureRecognizer to the view and pull interaction that way or access the information through the UIResponder.
On thing to remember is, make sure userInteractionEnabled is set to YES if you are going straight through the UIResponder otherwise you'll just end up ignoring the events.