从横屏旋转到竖屏后,UITableView表格的行为奇怪 (iPad)

4
在方法willRotateToInterfaceOrientation:duration:中,我试图读取UITableView旋转后的contentOffset。我创建了一个使用UITableViewController和tableHeaderView中的搜索栏的示例。
情况1: 假设设备处于纵向,并且我隐藏了搜索栏。 然后,我将设备旋转到横向。 之后,我不希望看到UISearchbar并且contentOffset保持不变。
情况2: 假设设备处于横向,并且我隐藏了搜索栏。 然后,我将设备旋转到纵向。 之后,我不希望看到UISearchbar并且contentOffset保持不变。
情况1按预期工作。情况2弹出搜索栏,而contentOffset为零。
有人知道为什么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

我知道明确设置tableHeaderView应该避免这种情况,但你是否尝试过使用-(CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section代理方法?尝试返回44.0并查看是否有所帮助。 - Bergasms
这个方法仅返回tableView:viewForHeaderInSection中header部分的高度(不是tableHeaderView的高度)。内容偏移为零确实很奇怪,希望这不是API中的错误。 - Vinh
好的,我基于你的代码创建了一个项目,但是我没有看到两种方向之间有任何区别。两者都返回了0/0,并且搜索栏仍然停留在屏幕上。我有两个(可能很天真的)问题:为什么你要使用dispatch而不是直接更改内容值?如果你只是将搜索栏滑出屏幕,为什么要更改contentInset而不是contentOffset? - mackworth
我试图在旋转过程中隐藏搜索栏。尝试在iPad的横屏模式下隐藏搜索栏,然后将设备旋转到竖屏模式。然后你会发现搜索栏会弹出来。我试图通过调整UIEdgeInsets来使UISearchbar保持在顶部锁定。 - Vinh
2个回答

2

我今天遇到了类似的问题,并找到了解决方案。 声明一个实例变量来维护tableView的contentOffset。 在调用 - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 方法时保留 contentOffset 值,在 - (void)viewWillLayoutSubviews 方法中应用它。我们需要重写这个方法。

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

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

这个方法没有任何刷新问题就解决了我的问题。

2
我认为我知道问题出在哪里:
UITableView具有默认的自动调整大小掩码。因此,将设备从纵向旋转到横向后,UITableView变小了(但偏移量没有改变)。如果用户现在回到纵向,则UITableView需要被拉伸并自动滚动到顶部。为了解决这个问题,我使用了一个变量来注册每个“用户滚动”,例如:
- scrollViewWillBeginDragging(注册) - scrollViewDidEndDecelerating(取消注册) - 在“scrollViewDidScroll”中,我检查滚动是否来自用户(如果是,则保存偏移值)
最后,在“willRotateToInterfaceOrientation”方法中,我将临时保存的偏移设置为UITableView以保持其在同一位置。
我希望会有更好的解决方案,因为我的解决方法有点棘手。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接