viewWillAppear
で、UISearchBar
のヘッダービューとしてUITableView
を追加しました。ビューが読み込まれると、UISearchbar
のcontentOffSetを使用して、UINavigationBar
の下のUITableView
を非表示にします。ユーザーがテーブルビューをプルダウンすると、検索バーが表示されます。
Headerviewを追加した後、以下のコードを使用して非表示にします。
self.tableView.contentOffset = CGPointMake(0, 40); //My searhbar height is 40
ただし、contentOffSet
がヘッダービューを隠すことはありません。何が間違いなのか。
これは私のために働いた:
// 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に入れます
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)
}
理由がわからない(今すぐ調査する時間がない)が、遅延0後にperformSelector
を使用してこの問題を解決しました。例:
- (void)viewWillAppear:(BOOL)animated {
...
[self performSelector:@selector(hideSearchBar) withObject:nil afterDelay:0.0f];
}
- (void)hideSearchBar {
self.tableView.contentOffset = CGPointMake(0, 44);
}
これは私のために働いた。
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];
私の場合、問題は私が電話したことでした
[_myGreatTableView reloadData];
_tableView.contentOffset.y
を取得する前に。これは常に「0」を返しました。
したがって、私はこれらのメソッドの順序を切り替えましたで動作します。
私の意見では、これはかなり奇妙な振る舞いです。オフセットが0を返したが、UIがテーブルのスクロール位置を維持したためです。
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];
}
このアプローチを使用すると、空の場合は常に検索バーを非表示にできます
layoutIfNeeded()で修正しました
self.articlesCollectionView.reloadData()
self.articlesCollectionView.layoutIfNeeded()
self.articlesCollectionView.setContentOffset(CGPoint(x: 0, y: 40), animated: false)
問題は自動マスキングです。下の画像のように、テーブルを選択し、すべての行が選択されていることを確認してください。
コード行は正常に機能しています。
contentOffset
のUITableView
の説明:
たとえば、高さが100のテーブルビューがある場合、そのコンテンツはビューよりも大きくなる場合があります(150など)。contentOffset
は、コンテンツのどこから開始するかをテーブルに通知します。 contentOffset = (0, 40)
と言うと、コンテンツは高さ40の後に表示されます。
注:コンテンツがスクロールされると、以前に設定されたcontentOffset
の影響はありません。
IOS 7/8/9ではself.automaticallyAdjustsScrollViewInsets = NO;私の場合は問題を解決しました
問題は検索バーのサイズにある可能性があります。次のコード行を試してください。
[searchBar sizeToFit];
テーブルをスクロールするときは、自分で検索バーを非表示にする必要があります。したがって、UITableView
ヘッダーとして配置しないでください。高さをゼロに設定することにより、非表示にすることができます。そうすれば、テーブルビューが自動サイズ変更に設定されている場合、拡大されます。
テーブルに常に少なくとも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
}