Reputation: 1248
I want the same behaviour as this
How do you hide navigation bar when scrolling in web view if the main view has a navigation bar without a navigationController? Navigation bars don't have the alternative via storyboard to check 'hide bars on swipe'.
This will not work either
self.navigationController.hidesBarsOnSwipe = true
This is what my SB looks like:
Regards
Upvotes: 1
Views: 2404
Reputation: 188
webView.scrollView.delegate = self
extension ViewController:UIScrollViewDelegate{
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
navigationController?.hidesBarsOnSwipe = velocity.y > 0
}
}
Upvotes: 1
Reputation: 10105
you might try the following solution:
Swift
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet var webView:UIWebView!
@IBOutlet var navigationBar:UINavigationBar!
@IBOutlet var navigationBarTop:NSLayoutConstraint!
var lastContentOffset:CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
self.webView.scrollView.delegate = self
self.webView.loadRequest(URLRequest(url: URL(string: "https://www.apple.com")!))
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
let threshold:CGFloat = 20.0
let delta = abs(self.lastContentOffset - scrollView.contentOffset.y)
if delta > threshold || scrollView.contentOffset.y <= 0 {
if self.lastContentOffset > scrollView.contentOffset.y && self.navigationBarTop.constant < 0 && (self.lastContentOffset < (scrollView.contentSize.height - scrollView.frame.height)) {
self.showNavBar(true)
} else if (self.lastContentOffset < scrollView.contentOffset.y && self.navigationBarTop.constant == 0 && (self.lastContentOffset > 0)) {
self.showNavBar(false)
}
}
self.lastContentOffset = scrollView.contentOffset.y;
}
func showNavBar(_ isVisible:Bool) {
UIView.animate(withDuration: 0.25, animations: {
self.navigationBarTop.constant = isVisible ? 0 : -(self.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height)
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
})
}
}
full source code here: https://github.com/mugx/AnimatedNavigationBar
Objective-C
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UIScrollViewDelegate>
@property IBOutlet UIWebView *webView;
@property IBOutlet UINavigationBar *navigationBar;
@property IBOutlet NSLayoutConstraint *navigationBarTop;
@property (nonatomic,assign) CGFloat lastContentOffset;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.webView.scrollView.delegate = self;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.apple.com"]]];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat threshold = 20.0;
CGFloat delta = fabs(self.lastContentOffset - scrollView.contentOffset.y);
if (delta > threshold || scrollView.contentOffset.y <= 0) {
if (self.lastContentOffset > scrollView.contentOffset.y && self.navigationBarTop.constant < 0 && (self.lastContentOffset < (scrollView.contentSize.height - scrollView.frame.size.height))) {
[self showNavBar:true];
} else if (self.lastContentOffset < scrollView.contentOffset.y && self.navigationBarTop.constant == 0 && (self.lastContentOffset > 0)) {
[self showNavBar:false];
}
}
self.lastContentOffset = scrollView.contentOffset.y;
}
- (void)showNavBar:(Boolean)isVisible {
[UIView animateWithDuration:0.25 animations:^{
self.navigationBarTop.constant = isVisible ? 0 : -(self.navigationBar.frame.size.height + UIApplication.sharedApplication.statusBarFrame.size.height);
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
@end
This is the first solution I thought, of course is not drag and drop, you have to link the respective IBOutlet. Anyway the mechanism I think is clear, leverage on scrollView delegate embedded in the webview, then calculate the delta offset in order to show/hide (with a smooth animation) your custom navigation bar. If something is not clear, I'll modify the answer.
Upvotes: 1