从Landscape到Portrait(iPad)旋转后UITableView的奇怪行为

时间:2012-11-09 10:18:20

标签: objective-c ipad uitableview contentoffset

我试图在方法

中旋转后读取tableview的contentOffset

willRotateToInterfaceOrientation:持续时间:。我使用UITableViewController和tableHeaderView中的搜索栏创建了一个示例。

情景1: 给定设备在纵向,我隐藏搜索栏 然后我将设备旋转到横向 之后,我希望不要看到UISearchbar和contentOffset保持不变。

场景2: 给定设备在横向,我隐藏搜索栏 然后我将设备旋转为肖像 之后,我希望不要看到UISearchbar和contentOffset保持不变。

方案1按预期工作。场景2弹出搜索栏,内容偏移为零

有人知道为什么ContentOffset为零吗?我希望它是44(搜索栏的高度)。

有什么方法可以解决这个问题吗?你会怎么做?

//
//  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

2 个答案:

答案 0 :(得分:2)

我想我知道问题所在:

UITableView具有默认的自动调整遮罩。因此,在将设备从纵向旋转到横向之后,UITableView变得越来越小(不会改变偏移)。如果用户现在回到纵向,则需要拉伸UITableView并自动滚动到顶部。为了解决这个问题,我使用一个变量来注册每个用户滚动"像

  • scrollViewWillBeginDragging(注册)
  • scrollViewDidEndDecelerating(unregistrate)
  • 在" scrollViewDidScroll"我检查滚动是否来自用户(如果来自用户保存偏移值)

最后在方法" willRotateToInterfaceOrientation"我将临时保存的偏移量设置为UITableView以使其保持在同一位置。

我希望有更好的解决方案,因为我解决这个问题的方法有点棘手。

答案 1 :(得分:2)

我今天遇到的类似问题,我找到了解决方法。 声明了一个实例变量,用于维护tableView的contentOffset。 在 - (void)期间保留contentOffset值willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration方法调用并将其应用于 - (void)viewWillLayoutSubviews方法。我们需要覆盖这种方法。

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

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

这解决了我的问题,没有任何令人耳目一新的问题。