How to intercept UIScrollView contentOffset changes from UITableView subclass? - iphone

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.

Related

How to get the contentOffset of a UIScrollView mid-scroll?

How would one get the contentOffset or similar information about a UIScrollView while the user is still scrolling? For example if I wanted to place an image as a header right above the content of a UIWebView, without the image being part of the WebView's scrollView, but have it update while the user scrolls, not just jumping to the position after they let go. How could I go about doing this?
In iOS 5, the UIWebView has a scrollView property which is the UIScrollView responsible for handling the scrolling. Prior to iOS 5 you can search the UIWebView's subviews property for the subview using [subview isKindOfClass:[UIScrollView class]].
Once you have the UIScrollView, you can then set its delegate property. In the delegate you can then respond to the scrollViewDidScroll: message when the user scrolls, and update the position/contents of your header view.
Added: 29/2/2012 - In order to preserve the UIWebView's functionality, you will need to forward your intercepted UIScrollViewDelegate methods to the UIWebView too. To do this, you can call the UIWebView at the end of all mandatory methods within the protocol and implement something like forwardInvocation: or forwardingTargetForSelector for the optional protocol methods. This will preserve your original UIWebView behavior and allow you to enhance it with your own logic.
Why can't you just put the header as a separate view above the UIWebView? Why does it have to be a subview?

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.

Access UIScrollViewDelegate from subclass of UITableView

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.

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 provide an own contentView for using -drawRect?

I want to use -drawRect: in an UITableViewCell subclass but it is covered by contentView. So the best option seems to be that I make a UIView subclass with my -drawRect: code and use that as contentView. But how could I feed my UITableViewCell subclass with that contentView?
UITableViewCell creates that on its own when the contentView property is accessed. Would I simply override the getter method and then provide my own view there?
Make a subclass of UIView and implement your drawing code in this objects drawRect method.
Add this subclass to the contentView of the cell upon initialisation.
[cell.contentView addSubview:customView];
No need to modify the cell's drawRect method.