UITableView not executing to scrollViewDidScroll or scrollViewShouldScrollToTop - iphone

I have a private table view in my UIViewController as follows
UIViewController<UIScrollViewDelegate, UITableViewDelegate> {
#private
UITableView *gTableView;
...
}
in my implementation i have set
gTableView.delegate=self;
gTableView.dataSource=self;
EDIT
The scrollViewWillBeginDecelerating and scrollViewDidScroll delegates are getting called but not the scrollViewDidScrollToTop.
What am I doing wrong now?

When used with a TableView, scrollViewDidScrollToTop only gets called with a scroll-to-top gesture (a tap on the status bar). Try using scrollViewDidEndDragging or scrollViewDidEndDecelerating to detect if scrollView.contentOffset.y is <= 0

Related

UITableView - get notification about scrolling

Is there any way to know, when the UITableView scrolled ? I need something that is the same like scrollViewDidScroll in scrollview.
If you set your UITableView's delegate to self, the view controller should call scrollViewDidScroll() when the view is scrolled:
myTableView.delegate = self
This works because UITableView is a subclass of UIScrollView.

UITableViewController - limit the scrolling

I have a UITableViewController which contains a View and a Table View Section.
View contains a label that indicates the title of the table.
My problem is that the scroll includes the View. What I want is to keep View static (exclude from scrolling) and to scroll only Table. (I use static cells)
Thanks.
The hierarchy of a UITableViewController is
- UIView
-- UIScrollView
---- UITableView
Initially you're in the UITableView when modifying items, so you'll want to add the portion that you do not want to scroll to the UIView (outside of our scrollView). So you'll need to call super a couple times like this:
[self.superview.superview.view addSubview:viewThatDoesNotScroll];
Since UITableView is a subclass of UIScrollView:
- (void)viewDidLoad {
[super viewDidLoad];
// mySubview is an instance variable, declared in .h file
[self.tableView addSubview:mySubview];
// here goes the rest of your code
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if(scrollView == self.tableView) {
mySubview.frame = CGRectMake(mySubview.frame.origin.x, scrollView.contentOffset.y, mySubview.frame.size.width, mySubview.frame.size.height);
}
}
The code was taken from WWDC '10 or '11 (I don't remember), so I'm sure it's the most appropriate way to do it.
Explanation: In -viewDidLoad you create your view and add it as a subview of your tableView. You can do it in -loadView or -init - it doesn't matter. The most important lines are in the -scrollViewDidScroll: method. This method is called whenever user drags the scrollView, so you can simply set the origin.y of your subview to contentOffset.y of the scrollView.
Do not UITableViewController. Use UIViewController and manage the views outside of the UITableView object. If you need, you can also implement UIViewControllerContainment to manage different views and different view controllers inside your custom view controller.

Why UITableView calls UIScrollView's delegate methods?

I have an application, in which I have a UITableView inside a UIView, which is again inside a UIScrollView, so the hierarchy becomes like this:
UIScrollView -> UIView -> UITableView
The data inside my UITableView is filled properly.
Now, my problem is that, When I scroll my UITableView, the UIScrollView's delegate method scrollViewDidEndDecelerating: and scrollViewDidEndDragging:: gets called.
I don't want this behavior, what should I do to stop this behavior?
Any one please Help,
Thank in advance!!!
UITableViewDelegate extends UIScrollViewDelegate. Hence the calling of the delegate methods.
To stop this you can set tableView.tag = 1000; when you alloc the tableView and in the UIScrollViewDelegate methods ( scrollViewDidEndDecelerating: and scrollViewDidEndDragging:: )add this at the very begining:
if(scrollView.tag == 1000)
return;
Because UITableView inherits from UIScrollView. So it shows all the properties and behaviours of UIScrollView. If you dont want this then please do one thing.
Assuming you have another scrollview in your page.
in the viewDidLoad or from the XIB (if you have your tableview in the XIB), set a tag for your tableview.
in code,
self.objYourTableView.tag = 101;
then in the scroll view delegate
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
if(!(scrollView.tag == 101))
{
// Go for your code to run.
}
}
So that your code will skip if it called by the table view. Other cases it works perfect. Hope this will help you.

Parent view -> Subview -> button -> subview method

I have a parentview with a ui view on it. This loads a subviewcontroller on viewdidload. The subviewcontroller has a button on it that is linked up on touch up inside to a subviewcontroller method called clicked.
This causes a bad access error to fire and crashes the app. My question is, is this setup possible or do I have to have the method in the parent view? The subview will be loaded in 8 different parentviews so I would like to keep the method in the subview.
What would be the correct way of doing this?
The good approach for this kind of setup is to have a protocol including the click message, a delegate property of type id in the view containing the button and a method in the same view that fires the delegated message like so [self.delegate clicked]. The TouchUpInside event is linked to that method in IB and the parent view set itself as delegate of the subview and conform itself to the protocol. It can sounds a bit tricky but its definitely the proper way to do.
the Protocol
#protocol viewWithButtonDelegate
-(void)buttonClicked:(UIButton*)button inView:(UIView*)view;
#end
in the subview interface
#interface viewWithButton {
...
id<viewWithButtonDelegate> delegate;
}
...
#property (nonatomic, retain) id<viewWithButtonDelegate> delegate
-(void)buttonClicked:(id)sender;
...
#end
in the subview implementation
-(void)buttonClicked:(id)sender {
if([sender class] == [UIButton class]) {
[self.delegate buttonClicked:(UIButton*)sender inView:self]
}
}
the controller interface is declared like this
#interface myController<viewWithButtonDelegate>
and finally in the controller implementation :
-(void)buttonClicked:(UIButton*)button inView:(UIView*)view {
//do something in response to button clicked
}
hope this helps...

How to detect scrolling of UITableView?

There is a similar question to this but answer is very general, vague.( Detecting UITableView scrolling )
Please don't dismiss. I am looking for concrete solution.
I have UITableView which has editable textfield and PickerView appears when another cell selected.
What I need is to hide firstResponder or PickerView when user starts scrolling this UITableView.
So far in question Detecting UITableView scrolling there's a sugestion that you should subclass UITableView. IF you subsclass UITableView still internal/private UIScrollView is not accessible.
How do I access UITableView's parent ScrollView (without breaking the law)?
Thanks.
You don't need to subclass UITableView to track scrolling. Your UITableViewDelegate can serve as UIScrollViewDelegate as well. So in your delegate class you can implement -scrollViewWillBeginDragging: or whatever UIScrollViewDelegate method you need in your situation. (as actually suggested in the question you mention)
To expand on Vladimir's answer, this is how I implemented this solution:
In .h file:
#interface MyViewController : UIViewController <UIScrollViewDelegate>
In .m file:
- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView {
//logic here
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
if (scrollView == myTableView){
// Your code here.....
}
}
I had the same problem, and I got some ideas from the answers above to fix it, but not only the app crashes if I want to refresh while the table view is being scrolled, but also it crashes if I scroll while it's being refreshed. So the extended solution to fix the problem under all circumstances is to:
1.1. Disable scrolling if the user has pressed the refresh button
1.2. Enable scrolling once the refresh process is done
2.1. Disable the refresh button if the user is scrolling
2.2. Enable the refresh button once the user is finished scrolling
To implement the first part (1.1., and 1.2.):
-(void)startReloading:(id)sender
{
...
self.tableView.userInteractionEnabled = NO;
// and the rest of the method implementation
}
-(void)stopReloading:(id)sender
{
self.tableView.userInteractionEnabled = YES;
// and the rest of the method implementation
}
To implement the second part (2.1., and 2.2.):
- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView
{
barButton.enabled = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
barButton.enabled = YES;
}
And as it's explained in the previous answer, UISCrollViewDelegate needs to be set in the .h file:
#interface MyTableViewController : UITableViewController <UIScrollViewDelegate>
P.S. You can use scrollEnabled instead of userInteractionEnabled, but it all depends on what you're doing, but userInteraction is the preferred option.