2

私は本のリーダーのようなものを構築しています。ユーザーが電話を回転させたときに、フォントサイズを大きくしたい。UITableViewテキストのチャンクを表示するために a を使用しています。

問題は、フォント サイズを大きくすると、テーブル ビューの行の高さが大きくなり、ポートレート モードで段落 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];
}

次に、ある回転のセルが別の回転のセルと異なることをtableViewが認識できるように、デキューセル名にinterfaceOrientation番号または単にテーブル幅を追加することをお勧めします。そのようです:

- (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 に答える