私はiOS開発にまったく慣れていません。現在、下にスクロールするとタブバーを非表示にしようとしていますが、上にスクロールするとタブバーが表示されます。ナビゲーションバーと同じようにアニメーション化してもらいたいです。ナビゲーションバーの場合は、属性インスペクターのオプションをクリックするだけです。ツールバーの例をいくつか見ましたが、タブバーを採用することはできません。
self.tabBarController?.tabBar.hidden = true
タブバーを非表示にするだけですが、ナビゲーションコントローラーのようにアニメーション化されていません。
これは、私が実際に本番アプリで使用しているコードです。
Swiftにあり、UITabBar.hidden
varも更新します。
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{
changeTabBar(hidden: true, animated: true)
}
else{
changeTabBar(hidden: false, animated: true)
}
}
他のコールバックメソッドを使用することもできます。
func scrollViewDidScroll(scrollView: UIScrollView) {
...
}
ただし、そうすることを選択した場合は、実際にtabBarを非表示にするヘルパーメソッドへの複数の呼び出しを処理する必要があります。
次に、tabBarの非表示/表示をアニメーション化するこのメソッドを追加する必要があります。
func changeTabBar(hidden:Bool, animated: Bool){
var tabBar = self.tabBarController?.tabBar
if tabBar!.hidden == hidden{ return }
let frame = tabBar?.frame
let offset = (hidden ? (frame?.size.height)! : -(frame?.size.height)!)
let duration:NSTimeInterval = (animated ? 0.5 : 0.0)
tabBar?.hidden = false
if frame != nil
{
UIView.animateWithDuration(duration,
animations: {tabBar!.frame = CGRectOffset(frame!, 0, offset)},
completion: {
println($0)
if $0 {tabBar?.hidden = hidden}
})
}
}
更新Swift 4
func changeTabBar(hidden:Bool, animated: Bool){
guard let tabBar = self.tabBarController?.tabBar else { return; }
if tabBar.isHidden == hidden{ return }
let frame = tabBar.frame
let offset = hidden ? frame.size.height : -frame.size.height
let duration:TimeInterval = (animated ? 0.5 : 0.0)
tabBar.isHidden = false
UIView.animate(withDuration: duration, animations: {
tabBar.frame = frame.offsetBy(dx: 0, dy: offset)
}, completion: { (true) in
tabBar.isHidden = hidden
})
}
Arielの回答に基づいて、Swiftのコードを更新しました。これは私のコレクションビューでうまく機能しました。
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0 {
changeTabBar(hidden: true, animated: true)
}else{
changeTabBar(hidden: false, animated: true)
}
}
func changeTabBar(hidden:Bool, animated: Bool){
let tabBar = self.tabBarController?.tabBar
if tabBar!.isHidden == hidden{ return }
let frame = tabBar?.frame
let offset = (hidden ? (frame?.size.height)! : -(frame?.size.height)!)
let duration:TimeInterval = (animated ? 0.5 : 0.0)
tabBar?.isHidden = false
if frame != nil
{
UIView.animate(withDuration: duration,
animations: {tabBar!.frame = frame!.offsetBy(dx: 0, dy: offset)},
completion: {
print($0)
if $0 {tabBar?.isHidden = hidden}
})
}
}
この回答は、ユーザーがスクロールしている間にアニメーションを追加するArielの回答を少し変更したものです。
extension ViewController:UIScrollViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{
//scrolling down
changeTabBar(hidden: true, animated: true)
}
else{
//scrolling up
changeTabBar(hidden: false, animated: true)
}
}
func changeTabBar(hidden:Bool, animated: Bool){
let tabBar = self.tabBarController?.tabBar
let offset = (hidden ? UIScreen.main.bounds.size.height : UIScreen.main.bounds.size.height - (tabBar?.frame.size.height)! )
if offset == tabBar?.frame.Origin.y {return}
print("changing Origin y position")
let duration:TimeInterval = (animated ? 0.5 : 0.0)
UIView.animate(withDuration: duration,
animations: {tabBar!.frame.Origin.y = offset},
completion:nil)
}
}
クラスをscrollViewのデリゲートとして設定し、scrollViewDidScroll:
メソッドでスクロールを実装することにより、UITabBarを正確に制御できます。
これが私のアプリケーションの例です。おそらく、必要に応じて簡単に変更できます。 UITabBarを含めるためのいくつかのヘルパー関数。
#define LIMIT(__VALUE__, __MIN__, __MAX__) MAX(__MIN__, MIN(__MAX__, __VALUE__))
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat scrollOffset = scrollView.contentOffset.y;
CGFloat scrollDiff = scrollOffset - self.previousScrollViewYOffset;
CGFloat scrollHeight = scrollView.frame.size.height;
CGFloat scrollContentSizeHeight = scrollView.contentSize.height + scrollView.contentInset.bottom;
CGFloat scrollOffsetGlobal = scrollOffset + scrollView.contentInset.top;
[self updateUITabBarY:[self UITabBarView].frame.Origin.y + scrollDiff];
self.previousScrollViewYOffset = scrollOffset;
}
- (UITabBar*) UITabBarView
{
for(UIView *view in self.tabBarController.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
return (UITabBar*) view;
}
}
return nil;
}
- (void) updateUITabBarY:(CGFloat) y
{
UITabBar* tabBar = [self UITabBarView];
if(tabBar)
{
CGRect frame = tabBar.frame;
frame.Origin.y = LIMIT(y, [self UITabBarMiny], [self UITabBarMaxY]);
tabBar.frame = frame;
}
}
- (CGFloat) UITabBarMiny
{
return [UIScreen mainScreen].bounds.size.height - [self UITabBarView].frame.size.height - [[UIApplication sharedApplication] statusBarFrame].size.height + 20.0f;
}
- (CGFloat) UITabBarMaxY
{
return [UIScreen mainScreen].bounds.size.height;
}
@ArielHernándezAmadorによると、Tabbarを非表示にした後の黒い画面に対する回答は、ViewDidLoad()でこのコード行を使用するだけです。見事に働いています...あそこにコメントすることができないので、私はここにこれを投稿しました。
viewDidLoad()
{
if #available(iOS 11.0, *) {
self.myScroll.contentInsetAdjustmentBehavior = .never
}
}
ここでmyScrollは、VCで使用しているScrollviewです。 VCと交換するだけです。