Access UIScrollViewDelegate from subclass of UITableView - iphone

I'm working on a project where I have to work lot of with UITableViews. So, I want to detect if the table view (UIScrollView) is scrolling.
First I handled it with the UIScrollViewDelegate in the UIViewController where my UITableView is added as a subview. Now, to keep the code clean, I want to subclass UITableView and in this class I have to access to the delegate methods of UIScrollView, e.g. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView.
But how can I do this? Is it possible?

All you have to do is implement - (void)scrollViewDidScroll:(UIScrollView *)scrollView delegate & detect if the scrolling is happening in your UITableView or somewhere else.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(scrollView == self.tableView)
{
//your logic here
}
return;
}

Those UIScrollViewDelegate methods must be defined in a class that is the delegate of the tableview that you want to handle scrolling changes of. If you put these methods in the implementation file of your UITableView subclass then you should set the tableview's delegate as itself:
[self setDelegate:self];
But then you also have to define your UITableViewDelegate and UITableViewDataSource methods in the UITableView subclass. This might complicate things if you want to use your UITableView subclass more than one place in your project. If I were you, I would double-think about my design and behave accordingly.

Related

Strange Behavior-Did select row touch not responding for UITableViewCell

I have a very strange problem,I don't know whether it is awkward to normal behavior of cells or not,it seems as if it is so!Hence I am giving it up to some one who can answer, apologize if any thing stupid in asking this question.Normally,when we touch a table view cell,what happens is it navigates to a view controller/a controller that is coded.Now what's strange here is it is not responding to selection,or touch.I have checked whether or not allows selection while editing is selected in IB or not.I have selected it,now the twist here is when I am touching a table view cell it is not responding,instead when I swipe it horizontally/when I long press the cell,it is navigating,really surprised at this strange behavior!I don't understand the reason why I need to swipe it to make selection of cell in table view work.This is also happening with button present below the table view!
I have searched for issues similar to my case,but I found just one question there it was suggested to check for this method,
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
But i haven't implemented that method at all,what I have actually is a tab bar with several items,where I have a controller called AddController,for accessing several attributes and strings etc.. declared in the controller,I am subclassing it as follows:
#interface ViewController : AddController
Now because it was specified in the question I saw,i.e. the link I gave,to check whether u are copying the same code in subclass controller page,I spoke about subclassing and what I did,hope every one understands it!
Can any one please guide me how to get out of this issue,and make table view cell respond to normal touches,any help is greatly appreciated!
Thanks all in advance :)
After doing some research I'm pretty sure that it is the UITapGestureRecognizer on the tableView caused you the problem. If you were like me having the text field in the cell and using the UITapGestureRecognizer to close the keyboard, here's my solution:
In the view that you implemented UITextFieldDelegate
(In my case I have a custom UITableViewCell called TextFieldCell),
Declare a UITapGestureRecognizer as a property:
#interface TextFieldCell : UITableViewCell <UITextFieldDelegate>
{
UITextField *theTextField;
UITapGestureRecognizer *gestureRecognizer;
}
#property (nonatomic,retain) UITextField *theTextField;
#property (nonatomic,retain) UITapGestureRecognizer *gestureRecognizer;
And initialize it in your view:
self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(closeKeyboard:)];
In the - (void)textFieldDidBeginEditing:(UITextField *)textField method, use superView to move up to your tableView and call addGestureRecognizer:
[self.superview.superview addGestureRecognizer:gestureRecognizer];
And in the - (void)textFieldDidEndEditing:(UITextField *)textField, just remove the gesture recognizer:
[self.superview.superview removeGestureRecognizer:gestureRecognizer];
This will totally solve the problem.
Did you use a UITapGestureRecognizer on your tableView? I had the exactly same problem as you did today, and then I figured out that it was the gesture recognizer that blurs my intention for selecting a row by tapping. When I removed it, the tableView was back to normal.
Hope this helps.
I had this same problem and solved it by ticking "Scrolling Enabled" in the table view attributes.
My table view doesn't need scrolling, so it doesn't affect the app in any other way, except now I don't get the first unresponsive tap after a swipe gesture.

UIView behind cells of a UITableView

I'm trying to insert a view behind the cells of a uitableview but I can't find a way to do it properly. Everytime I add a subview to self.view or self.tableview, it goes on the foreground, even if I use the method "sendSubviewToBack:" ...
Do someone have an idea on how to achieve it ?
PS : I don't want to use self.tableview.backgroundView because the view is fixed.
Thanks
I solved it by calling [self.view sendSubviewToBack:self.myBackgroundView] in tableView:willDisplayCell:forRowAtIndexPath:. This will put the view behind each cell.
What you experience is logical. The self.view of a UITableView is indeed the table view. If you insert a subview, it is inserted on top of the table view - and there is no way to send it to the back.
Solution 1
The most flexible solution is to switch to a UIViewConntroller and implement the table view behaviour yourself. You need to
insert your own table view as a #property. This is now a subview of self.view. You can do this in code or in IB.
declare and implement the <UITableViewDelegate> and <UITableViewDatasource> protocols
set the delegate and datasource properties of the table view to self
insert any other subviews at will and shuffle them around as you wish.
Solution 2
If you just want to display something behind the tableView you might be able to use the table view property backgroundView. This will display behind the cells, but you will have limited control over the view's size (which you could again solve with further subviews of the background view). Also, you need to make sure your cells are transparent.
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index
with index 0 will take the View to position which is the back-most one.
This is a method on UIView.
Since UITableView Inherits from UIScrollView : UIView : UIResponder : NSObject. I guess this would help.

How to add a UIView above a UITableView in iOS?

I am using the xcode template to create a UITableView application with UINavigationController.
I need to add a UIView (at fixed position) between the UINavigationBar and the UITableView. How to do that ?
Thanks.
You can do this by setting the UITableView's tableHeaderView property.
UITableView class reference
tableHeaderView
Returns an accessory view that is displayed above the table.
#property(nonatomic, retain) UIView *tableHeaderView
Discussion The default value is nil. The table header view is
different from a section header.
Availability Available in iOS 2.0 and later.
Add UIView and UITableView as subviews of UIView and then position their height, width and x, y position from the Size Inspector in Interface builder or Use CGRectMake in objective-c
you need to implement following UITableview delegate methods
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
Step 1)
Create a header view as, set outlet to that view.
#property(nonatomic,strong)IBOutlet UIView *viewHeader;
Setp 2)
Add following single line code on viewDidLoad
[self.tableview setTableHeaderView:self.viewHeader];
Done!!!
Views are maintained in a hierarchy in iOS. They are maintained essentially as an array with the latest view first. To insert some view below one view or above another you just need to manipulate this.
All this is theory, I have not done what you want. So dont hold a grudge against me ;) this is a friendly suggestion.
[self.view insertSubview:yourNewView belowSubview:navigationController];

Tap Status Bar Time

I am using a UITableView in my app. After scrolling down, if I tap on the status bar time, the table is repositioned to the top. Any idea how this is done and is it possible to intercept the action. TIA, Jim B
A UITableView is an extension of UIScrollView, and UITableViewDelegate is an extension of UIScrollViewDelegate.
A UIScrollViewDelegate can implement this method:
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
That will allow you to intercept it.
You can also just turn it off with your tableview's "scrollsToTop" property.
If you just want to know when it happens, you can use this delegate method:
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView

How to intercept UIScrollView contentOffset changes from UITableView subclass?

Actually, a UITableView is a UIScrollView (inherits from that). Now, I made a UITableView subclass and added this line of code to it:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"contentOffset: %#", NSStringFromCGPoint(self.contentOffset));
}
For some reason this is never called when I scroll the table view. But since UITableView has a delegate property on it's own, I assume that it must implement UIScrollViewDelegate protocol and is the delegate for the scroll view itself. Isn't it?
How could I intercept scroll position changes? I want to read them only. Probably I couldn't set them with contentOffset, right?
Probably I couldn't set them with
contentOffset, right?
As UITableView inherits from UIScrollView you can get and set its contentOffset property.
Note also that UITableViewDelegate protocol is defined the following way:
#protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
That is it conforms to UIScrollViewDelegate protocol as well so your tableView's delegate(not UITableView itself) can implement any UIScrollViewDelegate methods and they should get called fine.
Just implement setContentOffset: and call super after you read the values you want. A UITableView is a UIScrollView so you can scroll it by calling setContentOffset: as well.