web-dev-qa-db-ja.com

UITableView contentOffSetが正しく機能していません

viewWillAppearで、UISearchBarのヘッダービューとしてUITableViewを追加しました。ビューが読み込まれると、UISearchbarのc​​ontentOffSetを使用して、UINavigationBarの下のUITableViewを非表示にします。ユーザーがテーブルビューをプルダウンすると、検索バーが表示されます。

Headerviewを追加した後、以下のコードを使用して非表示にします。

self.tableView.contentOffset = CGPointMake(0, 40); //My searhbar height is 40

ただし、contentOffSetがヘッダービューを隠すことはありません。何が間違いなのか。

21
JiteshW

これは私のために働いた:

// contentOffset will not change before the main runloop ends without queueing it, for iPad that is
dispatch_async(dispatch_get_main_queue(), ^{
    // The search bar is hidden when the view becomes visible the first time
    self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.searchBar.bounds));
});

-viewDidLoadまたは-viewWillAppearに入れます

31
maz

IOS SDKの以前のバージョンでは、viewWillAppearなどのメソッドはメインスレッドで実行されていましたが、バックグラウンドスレッドで実行されるようになり、問題が発生するようになりました。

ほとんどのコールバックはバックグラウンドスレッドで起動する傾向があるため、UI呼び出しを行うときは常にスレッドセーフを確認してください。

メインスレッドのコンテンツオフセットへの変更をディスパッチします。

目的C

dispatch_async(dispatch_get_main_queue(), ^{
    CGPoint offset = CGPointMake(0, self.searchBar.bounds.height)
    [self.tableView setContentOffset:offset animated:NO];
});

Swift

DispatchQueue.main.async {
            let offset = CGPoint.init(x: 0, y: self.searchBar.bounds.height)
            self.tableView.setContentOffset(offset, animated: false)
        }
21
Matthew Cawley

理由がわからない(今すぐ調査する時間がない)が、遅延0後にperformSelectorを使用してこの問題を解決しました。例:

- (void)viewWillAppear:(BOOL)animated {
    ...
    [self performSelector:@selector(hideSearchBar) withObject:nil afterDelay:0.0f];
}

- (void)hideSearchBar {
    self.tableView.contentOffset = CGPointMake(0, 44);
}
19
deRonbrown

これは私のために働いた。

self.tableView.beginUpdates()
self.tableView.setContentOffset( CGPoint(x: 0.0, y: 0.0), animated: false)
self.tableView.endUpdates()

Objective-C:

[_tableView beginUpdates];
[_tableView setContentOffset:CGPointMake(0, 0)];
[_tableView endUpdates];
4
Kishor

私の場合、問題は私が電話したことでした

 [_myGreatTableView reloadData];

_tableView.contentOffset.yを取得する前に。これは常に「0」を返しました。

したがって、私はこれらのメソッドの順序を切り替えましたで動作します。

私の意見では、これはかなり奇妙な振る舞いです。オフセットが0を返したが、UIがテーブルのスクロール位置を維持したためです。

2
Mexx

1時間のテストの後、100%動作する唯一の方法は次のとおりです。

-(void)hideSearchBar
{
    if([self.tableSearchBar.text length]<=0 && !self.tableSearchBar.isFirstResponder)
    {
        self.tableView.contentOffset = CGPointMake(0, self.tableSearchBar.bounds.size.height);
        self.edgesForExtendedLayout = UIRectEdgeBottom;
    }
}

-(void)viewDidLayoutSubviews
{
    [self hideSearchBar];
}

このアプローチを使用すると、空の場合は常に検索バーを非表示にできます

2
Kappe

layoutIfNeeded()で修正しました

    self.articlesCollectionView.reloadData()
    self.articlesCollectionView.layoutIfNeeded()
    self.articlesCollectionView.setContentOffset(CGPoint(x: 0, y: 40), animated: false)
2
Blank

問題は自動マスキングです。下の画像のように、テーブルを選択し、すべての行が選択されていることを確認してください。

enter image description here

0
Dhara

コード行は正常に機能しています。

contentOffsetUITableViewの説明:

たとえば、高さが100のテーブルビューがある場合、そのコンテンツはビューよりも大きくなる場合があります(150など)。contentOffsetは、コンテンツのどこから開始するかをテーブルに通知します。 contentOffset = (0, 40)と言うと、コンテンツは高さ40の後に表示されます。

注:コンテンツがスクロールされると、以前に設定されたcontentOffsetの影響はありません。

IOS 7/8/9ではself.automaticallyAdjustsScrollViewInsets = NO;私の場合は問題を解決しました

0
Saumil Shah

問題は検索バーのサイズにある可能性があります。次のコード行を試してください。

[searchBar sizeToFit];
0
uranpro

テーブルをスクロールするときは、自分で検索バーを非表示にする必要があります。したがって、UITableViewヘッダーとして配置しないでください。高さをゼロに設定することにより、非表示にすることができます。そうすれば、テーブルビューが自動サイズ変更に設定されている場合、拡大されます。

0
parilogic

テーブルに常に少なくとも1つの行がある場合は、テーブルの最初の行までスクロールするだけで、検索バーは自動的に非表示になります。

let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)

self.tableView.selectRowAtIndexPath(firstIndexPath、animated:false、scrollPosition:.Top)

上記のコードをviewDidLoadに配置すると、tableViewがまだロードされていないためエラーがスローされます。そのため、この時点ではviewDidAppear tableViewはすでにロードされています。

viewDidAppearに配置すると、tableViewを開くたびに上部にスクロールします。

たぶん、tableViewがUITabBar View Controllerであるときや、セグエを実行してから戻ってくるときなど、tableViewが開いたままの場合、この動作は望ましくありません。最初のロードで一番上までスクロールするだけの場合は、変数を作成して最初のロードかどうかをチェックし、一度だけ一番上までスクロールできるようにします。

最初に、View ControllerクラスでisInitialLoadという変数を定義し、「true」に設定します。

var isInitialLoad = true

そして、viewDidAppearでisInitialLoadがtrueであるかどうかを確認し、trueである場合は、一番上までスクロールしてisInitialLoad変数をfalseに設定します。

if isInitialLoad {
    let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
    self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)
    isInitialLoad = false
}
0
drdrdrdr