How to Stop UIWebView from “bouncing” vertically scrolling bottom? - ios

My question is the same as this question, but has one difference. When I scroll to top refresh my website, I want stop bouncing only to the end of the bottom scroll. How do I do this?

You can try like this :
override func viewDidLoad() {
super.viewDidLoad()
webview.scrollView.delegate = self
}
func scrollViewDidScroll(scrollView: UIScrollView) {
if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height) {
scrollView.setContentOffset(CGPointMake(scrollView.contentOffset.x, scrollView.contentSize.height - scrollView.frame.size.height), animated: false)
}
}
Set the delegate of your webview and set the content offset of the webview's scrollview
Ref taken from: https://stackoverflow.com/a/14084747/4557505

Personally in Xcode 7.3 in Swift, I Simply add this in the viewDidLoad Function:
UIWebview.scrollView.bounces = false;

I think you can also set the scrollview's bounces
like this,It's simple
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView.contentOffset.y > 0) {
scrollView.bounces = NO;
}else{
scrollView.bounces = YES;
}
}

Related

How to show / hide custom view depending the contentOffset of my tableview?

I have a chat app and I'm trying to show a custom view that I've made when the user scrolls to the top, also hide it if it's on the bottom of tableview. (like whatsapp does it)
To be honest I'm struggling with the logic of show/hide button.
Tried to save the contentOffset.y of my tableview right after I reload the data so I'll know that's the bottom, and if it's smaller to show the custom view, but mainTableView.contentOffset.y it's always 0.
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if (scrollView == mainTableView) {
print(mainTableView.contentOffset.y)
if let point = startingPointForView {
//where var startingPointForView: CGFloat?
// and tried to save it after I reload the data
//self.startingPointForView = self.mainTableView.contentOffset.y
// but it's always 0
}
// Show and hide button logic
}
}
An image of what I m trying to achieve: https://imgur.com/ZkYEi2P
try this code to hide/show custom view according to UIscrollview contentOffset
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let scrollViewContentHeight = scrollView.contentSize.height
let scrollViewHeight = scrollView.frame.height
if scrollView.contentOffset.y < (scrollViewContentHeight - scrollViewHeight){
//Custom view show
}else{
//Custom view Hide
}
}
May be this code will help you
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y > 0 {
// down
button.isHidden = false
} else {
// up
button.isHidden = true
}
}
For someone who is looking to hide a button when tableview is scrolling can use below code:
var previousContentOffset: CGFloat = CGFloat()
extension YourViewController: UIScrollViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.yourTableView{
let currentContentOffset = scrollView.contentOffset.y
if (currentContentOffset > previousContentOffset) {
// scrolling towards the bottom
if scrollView.contentOffset.y > 50 {
self.yourButton.isHidden = true
} else {
self.yourButton.isHidden = false
}
} else if (currentContentOffset < previousContentOffset) {
// scrolling towards the top
let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height
// Change 10.0 to adjust the distance from bottom
if maximumOffset - currentContentOffset <= 10.0 {
self.yourButton.isHidden = true
} else {
self.yourButton.isHidden = false
}
}
previousContentOffset = currentContentOffset
}
}
}

iOS - scrollViewDidEndDecelerating runs for both scrollView and collectionView

I have a VC that contains a collectionView and a scrollView. I put this code to change current page of pageController by scrolling in scrollView :
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
}
It works nice for scrollView but the problem is when i even scroll in collectionView it declares and causes unwanted changing in pageController!
What should i do?
In addition to the answers posted above, You can make use of the tag property of the view.
Just assign a tag (Int) to your scrollview either in xib or via code.
yourScrollView.tag = 10
And in the scrollview delegate method check for this tag:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView.tag == 10 {
///Your scrollview was scrolled
} else {
// Collection view was scrolled
}
}
if scrollView == yourScrollView{
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
}
check if the instance running the method is actually your scrollView
First you have to understand bit detail about UICollectionView. The UICollectionView is subclassed from UIScrollView. That's why its getting called for both the scrolling (Scrolling collection view and scrolling scroll view). You can do like this to differentiate what type of scrolling it is,
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == "Your scrollView outlet name" { // Scroll view
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
} else {
// Collection view
}
}
Thanks.
You need to check the scrollView inside the scrollViewDidEndDecelerating if it is your scroll view or your collection view.
Just add an if scrollView == myScrollView before doing the 2 lines of code you have.
Your code shoudl look like this
func
scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == myScrollView {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
}
}

Easiest way to disable back scrolling in scrollview

I want to stop backward scrolling on ScrollView after user scrolls to the next page. How can I do that.
I tried the following two codes, but the first one does not have any effect
self.scrollView.contentOffset = CGPointMake(self.view.frame.width,0)
and the second only disables the forward scrolling.
self.scrollView.contentSize = CGSizeMake( 2 * scrollWidth, scrollHeight);
To disable scrolling in one direction you implement the UIScrollViewDelegate method scrollViewDidScroll and put your logic there. For instance this TableViewController can only ever scroll down, because if the user tries to scroll up, we just overwrite the contentOffset, effectively undoing their scroll before they see it.
class ViewController: UITableViewController {
var lastScrollPosition = CGPoint.zero
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard scrollView.contentOffset.y > lastScrollPosition.y else {
scrollView.setContentOffset(lastScrollPosition, animated: false)
return
}
lastScrollPosition = scrollView.contentOffset
}
}
If your cell is equal in size to your screen, you can apply the following option, which is very smooth:
var lastScrollPosition = CGPoint.zero
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView.contentOffset.x == lastScrollPosition.x + UIScreen.main.bounds.width {
lastScrollPosition.x += UIScreen.main.bounds.width
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard scrollView.contentOffset.x > lastScrollPosition.x else {
scrollView.setContentOffset(lastScrollPosition, animated: false)
return
}
}

iOS how to check if go to the bottom of webView

Is there any event I can notify the supper view?
I try the scrollViewDidScroll. But it don't be called.
-(void)scrollViewDidScroll: (UIScrollView*)scrollView
{
NSLog(#"At the bottom...");
}
You must set the delegate of scrollview which in the webview to self first. So that, scrollViewDidScroll: could be call when you scroll the webview. So, try this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.webview.scrollview.delegate = self;
}
- (void)scrollViewDidScroll:(UIScrollView*)scrollview
{
CGPoint offset = scrollView.contentOffset;
CGRect bounds = scrollView.bounds;
UIEdgeInsets inset = scrollView.contentInset;
CGFloat currentOffset = offset.y + bounds.size.height - inset.bottom;
if (currentOffset - scrollView.contentSize.height <= 0)
{
NSLog(#"At the bottom...");
}
}
If you have an instance of webView, you can get the reference of its scrollView by doing,
webView.scrollView. Set its delegate to self like so:
webView.scrollView.delegate = self;
Now, make sure you have implemented UIScrollViewDelegate in your class where you have an instance of the webView. Implement the below the code that tells you whether you have reached the bottom.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
if (bottomEdge >= scrollView.contentSize.height) {
//This means that you have reached the end.
}
}
To get the call in scrollView delegate methods you need to assign the delegate for webview scroll view like this:
webview.scrollView.delegate = self;
Also Conform the UIScrollViewDelegate in .h file like this:
#interface MyController : UIViewController <UIScrollViewDelegate>
#end
If anyone is interested on how this is done in Swift 4, here it is:
Set the webviews' scrollView delegate to self in viewDidLoad() self.webView.scrollView.delegate = self
Extend your class from UIScrollViewDelegate
Implement the method scrollViewDidScroll() which will handle the scroll events
(this particular implementation is used to check if the user has scrolled to the bottom of the webview's content)
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let bottom = scrollView.contentOffset.y + scrollView.frame.size.height
if (bottom >= scrollView.contentSize.height) {
// Do something here
}
}

Detect UITextView scroll location

I am trying to implement a form of a Terms & Conditions page where the "Proceed" button is only enabled once the user has scrolled to the bottom of a UITextView. So far I have set my class as a UIScrollView delegate & have implemented the method below:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSLog(#"Checking if at bottom of UITextView");
CGPoint bottomOffset = CGPointMake(0,self.warningTextView.frame.size.height);
//if ([[self.warningTextView contentOffset] isEqualTO:bottomOffset])
{
}
}
I have commented the if statement because I am not sure how to check if the UITextView is at the bottom.
UITextView is a UIScrollView subclass. Therefore the UIScrollView delegate method you are using is also available when using UITextView.
Instead of using scrollViewDidEndDecelerating, you should use scrollViewDidScroll, as the scrollview may stop scrolling without deceleration.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height)
{
NSLog(#"at bottom");
}
}
A Swift version for this question:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height {
print( "View scrolled to the bottom" )
}
}
This should solve it. It works. I am using it.
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
float bottomEdge = scrollView.contentOffset.y + scrollView.frame.size.height;
if (bottomEdge >= scrollView.contentSize.height)
{
// we are at the end
}
}

Resources