Question

I was trying to read the contentOffset of the tableview after rotation in the method

willRotateToInterfaceOrientation:duration:. I created a sample using UITableViewController with a searchbar in the tableHeaderView.

Scenario 1: Given device is in Portrait and I hide the searchbar Then I rotate the device to landscape After that I would expect NOT to see UISearchbar and contentOffset stay same.

Scenario 2: Given device is in Landscape and I hide the searchbar Then I rotate the device to portrait After that I would expect NOT to see UISearchbar and contentOffset stay same.

Scenario 1 is working as expected. Scenario 2 is popping out the Searchbar and the contentoffset is Zero

Does anybody know why the ContentOffset is Zero? I would expect it to be 44 (height of the searchbar).

Is there any way to solve this? How would you do it?

//
//  ViewController.m
//  test
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{

    //is necessary to prevent showing searchbar
    dispatch_async(dispatch_get_main_queue(), ^{


        double y = self.tableView.contentOffset.y;

        self.tableView.contentInset = UIEdgeInsetsMake(-1*y, 0, 0, 0);

        NSLog(@"y %f",y);
        NSLog(@"Begin offset %@",NSStringFromCGPoint(self.tableView.contentOffset));
    });

}

- (void)viewDidAppear:(BOOL)animated{

    self.tableView.tableHeaderView = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 44)];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 0;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...

    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

}

@end
Was it helpful?

Solution

I think I know where the problem is:

The UITableView is has the default autoresizing mask. So after rotating the device from portrait to landscape then the UITableView is getting smaller (which doesnt change the offset). If the user now turns back to portrait, then the UITableView needs to be stretched and automatically scroll to the top. To solve this problem I used a variable to registrate every "user scrolling" like

  • scrollViewWillBeginDragging (registrate)
  • scrollViewDidEndDecelerating (unregistrate)
  • in"scrollViewDidScroll" I check wether the scrolling is coming from user or not (if it is from user save the offset value)

Finally in the method "willRotateToInterfaceOrientation" I set the temporary saved offset to the UITableView to keep it on the same position.

I hope there will be better solution, because my way to solve this, is a bit tricky.

OTHER TIPS

I've a similar issue which I encountered today and I found a solution for this. Declared an instance variable which maintains the contentOffset of the tableView. Preserving the contentOffset value during - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration method call and applying it in - (void)viewWillLayoutSubviews method. We need to override this method.

- (void)willRotateToInterfaceOrientation(UIInterfaceOrientation)toInterfaceOrientation      duration:(NSTimeInterval)duration
{
    self.contentOffset = self.tableView.contentOffset;
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    self.tableView.contentOffset = self.contentOffset;
}

This fixed my problem without any kind of refreshing issues.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top