2

我正在为一本书构建类似阅读器的东西。当用户旋转手机时,我想增加字体大小。我正在使用 aUITableView来显示文本块。

问题是,增加字体大小会增加表格视图中行的高度,如果我在纵向模式下阅读第 320 段,我会在横向模式下得到 280 或类似的东西。

我已经使用以下代码设置了一个轮换通知侦听器:

    UIDevice *device = [UIDevice currentDevice];                
    [device beginGeneratingDeviceOrientationNotifications];
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self                                
           selector:@selector(orientationChanged:)
               name:UIDeviceOrientationDidChangeNotification
             object:device];

并尝试在旋转前保存最后一段索引,然后在旋转后向下滚动到它,但我似乎无法达到预期的效果。

处理这种情况的最佳方法是什么?我在哪里实际实施“之前”和“之后”的轮换状态?

我希望它可以在 iOS 4+ 上运行。

4

6 回答 6

5

Said Ali Samed 回答的Swift 3willRotateToInterfaceOrientation版本(didRotateFromInterfaceOrientation已弃用):

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
    coordinator.animate(alongsideTransition: { context in
            // Save the visible row position
            self.visibleRows = self.tableView.indexPathsForVisibleRows!
            context.viewController(forKey: UITransitionContextViewControllerKey.from)
        }, completion: { context in
            // Scroll to the saved position prior to screen rotate
            self.tableView.scrollToRow(at: self.visibleRows[0], at: .top, animated: false)
        })
}
于 2016-09-29T20:47:43.870 回答
4

使用委托方法 willRotateToInterfaceOrientation: 将可见单元格存储在数组中,然后使用 UITableView 的另一个委托方法 didRotateFromInterfaceOrientation: 滚动到您之前存储在数组中的可见索引路径。这是推荐的,您不必依赖不同线程中不一致的 0.2 秒等待来处理旋转后事件。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    // Save the visible row position
    visibleRows = [tableview indexPathsForVisibleRows];
}

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    // Scroll to the saved position prior to screen rotate
    [tableView scrollToRowAtIndexPath:[visibleRows objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
于 2014-09-22T12:17:22.593 回答
3

由于我无法得到一个好的答案,我会回答自己。我到处寻找,但找不到一种方法来做我想做的事,所以我只是使用该shouldAutorotateToInterfaceOrientation方法来增加字体的大小,然后启动一个休眠 0.2 秒的小线程,然后滚动到所需的行。谢谢你的帮助。

编辑:使用委托方法 willRotateToInterfaceOrientation: 将可见单元格存储在数组中,然后使用委托方法 didRotateFromInterfaceOrientation: 滚动到您在数组中记录的可见索引路径。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    // Save the visible row position
    visibleRows = [tableview indexPathsForVisibleRows];
}

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    // Scroll to the saved position prior to screen rotate
    [tableView scrollToRowAtIndexPath:[visibleRows objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
于 2012-09-04T10:13:34.413 回答
2

一种简单的方法是存储顶部可见单元格的索引路径,更改字体大小然后恢复顶部单元格:

NSIndexPath* topCellIndexPath = [[_tableView indexPathsForVisibleRows] objectAtIndex:0];
//Insert code to change font size here
[_tableView scrollToRowAtIndexPath:topCellIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];

可以将此代码放入在方向更改时运行的任何方法中,例如orientationChanged:您在问题中放入的方法。

这不会考虑将单元格向下滚动到一半,因此如果单元格的高度很大,它将无法正常工作,并且需要使用内容偏移的更复杂的方法。让我知道是否是这种情况。

于 2012-09-04T08:13:05.137 回答
0

首先,要重新加载所有表格单元格,请使用[self.tableView reloadData]

UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath其次,在 (方法中添加负责收缩的代码行。

例子:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//Some identifier and recycling stuff

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    //Make labels smaller
}
else {
    //Make them bigger
}
}

或者你可以updateCellForRotate:forRow:在制作它们时调用你的方法。但我不确定该功能是如何工作的,所以我不能太具体。

于 2012-09-04T09:29:15.970 回答
0
  - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)
fromInterfaceOrientation 
{
NSLog(@"didRotateFromInterfaceOrientation:%d",fromInterfaceOrientation);
[tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];
}

然后我建议将 interfaceOrientation 编号或简单的表格宽度添加到出列单元格名称中,这样 tableView 就知道一个旋转中的单元格与另一个旋转中的单元格不同。像这样:

- (UITableViewCell *)tableView:(UITableView *)tv
     cellForRowAtIndexPath:(NSIndexPath *)indexPath
     withType:(NSString *)s_type
{

UITableViewCell *cell = nil;
// add width of table to the name so that rotations will change the cell dequeue names
s_cell = [s_cell stringByAppendingString:
          [NSString stringWithFormat:@"%@%d",@"Width",(int)tv.bounds.size.width]
          ];

NSLog(@"%@",s_cell);
cell = [tv dequeueReusableCellWithIdentifier:s_cell];
if( cell == nil ) { 
    cell = [[[UITableViewCell alloc]
             initWithFrame:CGRectZero reuseIdentifier:s_cell] autorelease];
    }
}
于 2012-09-04T09:40:47.867 回答