ios scrollview - subview out of bounds vertically - ios

I have a dilemma that I cant get my head around to why it act as it does. I have some images that describes the problem. I have a sb:
note! the Image view and the mapview are on top of eachother. Toggling hidden or not depending if I have coords or not to display on map.
I add some dynamic text programmatically under the Sb UIView (and set some constraints. so it looks like this in the end:
Problem now is that if i scroll down a bit so that it looks like this:
Then if I hit the mapbutton to go to nextview that containts a bigger mapview and then return to this view. The scrollview is stuck with parts of the map under the navbar. I can ofc force a scrolldown and see the rest of the mapview but when I release it bounces back and party hides under the navbar once again.
I dont understand shit. And tell me if you want me to try to explain this better its 1.30am and my eyes can barely stay open. But still - any help or pointers are valuable to me.
/Pedro

You can scroll to the top of a UIScrollView using [scrollView setContentOffset:CGPointMake(0,0) animated:NO];.

Related

XCUITests: Can't tap element on scrollview while views are stack on each other

Sample Project
This is a sample project that showing the issue. It's storyboard based, but method of building interface doesn't matter. It's UIViewController with UIScrollView for entire screen and 128 pts height view that is on top of this UIScrollView.
Inside scroll view there is an UIView that has 2000 pts height and UIButton in the center.
Initial State
After light scroll
At the bottom of UIScrollView
Link here: https://github.com/JakubMazur/UITestsDemo
Problem
I'm trying to tap this green button with XCUITest using app.buttons["Tap Me!"].tap()
XCUITest get identifiers from elements on screen for entire scroll view that works fine.
According to this reply on a thread on Apple Developer Forum written by Apple Framework Engineer I shouldn't scroll manually to get to the button and yes, this is partially true.
What is happening when code from (1) is executed is that button is scrolled just enough to be visible on screen but it's still not hittable, because other (purple view) is on top of UIScrollView
What is working
If I run a test written like this:
func testThatDoWorkButItsSlow() {
app.scrollViews.firstMatch.swipeUp()
app.buttons[buttonLabel].tap()
}
that is scrolling up and then looks for a button this will work, but it's slow and so inaccurate that is hardly usable.
What I cannot do
Disabling userInteractions on purple view. In real example I still need touches for this (purple) view.
Questions
Is there a way to use precise scrolling in XCTest for this case?
Or is there a way to set contentOffset scrollview to other value that will make this button more centered on a screen compared to action of tap()?
Or there is a way to fast scroll to the bottom (without animations) and maybe moving only up for each element?
My recommendation here would be to use the XCUICoordinate.press(forDuration:thenDragTo:) method to scroll.
https://developer.apple.com/documentation/xctest/xcuicoordinate/1615003-press
You can create a XCUICoordinate for the yellow view, then drag it slightly upwards to expose the button and make it hittable.
In most cases, the automatic scroll should work, but it seems like in this case a manual scroll/drag is necessary.
The UI Testing should replicate human interactions. You cannot expect from a human being to scroll "153px", you can just expect to "scroll until".
You can try something like :
while (!app.buttons["Tap Me!"].isHittable) {
app.swipeUp()
}
NB: You may also want to add a condition to leave the while loop if you can't find the button after a reasonable amount of attempts

Horizontal UIScrollview always bouncing back, even after setting contenSize bigger - iOS

I have implemented a horizontal UIScrollview (adding buttons into it) but it always bounces back to original position after I scroll it. Searched a lot but the answers were of no luck as yet.
This is the scroll view below, of the same width as screen,
And this is the view inside it, which is of 800+ width,
Also in me class, I have implemented the following code:
_imageEffectsScrollView.contentSize = CGSizeMake(832, 80);
In fact it just now scrolls a little bit, instead of bouncing back ( like before ):
Please help, how can I make it scroll properly. Thanks!

UIWebview in UIScrollview send vertical scroll event to scrollview

So i have a UIWebView that is meant to only scroll horizontally, and its in a UIScrollView that is only meant to scroll vertically. I have almost managed to achieve this, but i have a slight problem.
The UIWebiew's scroll content height is set to the height of the webviews frame, so that it wont scroll vertically, but even when this is the case, it still seems to consume the vertical scrolling event (sometimes), since i can see the side scroll bar show, but it wont scroll (and doesnt scroll the scrollview that the webview is contained in).
It needs to be like this because there are some elements that need to scroll vertically with the webview, but not horizontally (think of the safari app how the addressbar scrolls with the webview)
does anyone know how i would pass the vertical scroll event through but keep the horizontal scroll event for the UIWebView?
i had a look at this answer but its not quite what im looking for
update:
so typically just after i ask the question i find a suitable answer on another question... (had been searching for a few hours now) this answer should do the trick for me, ill give it a go and report back
Just set
scrollView.alwaysBounceVertical = NO;
scrollView.contentSize = CGSizeMake(
scrollView.frame.size.width, scrollView.contentSize.height);
scrollView.showsVerticalScrollIndicator = NO;
Edit:
doesn't seems to work. Too bad..
Try implementing
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gst
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)gst2 {
return YES;
}
..in your view containing the scrollView and webView, or even the scrollView itself (containing the webView).
So the solution i found that i posted in the question works for the most part, it does exactly what i need, but for some reason after a webpage loads, it scrolls the headerbar away showing just the webpage, which isnt the end of the world but its not pretty. it seems the event fires after the webViewDidFinishLoad: so i cant just reposition it back to the top. Ill keep tinkering around, maybe i can find out why its doing it.

UIWebView contentInset without extra height at bottom

I'm creating a view controller that uses a web view which slides behind the navigation bar and status bar. To do this, I'm setting the webView.scrollView.contentInset property to have a top inset of 64.
However, this doesn't shrink the amount of area the web view wants to take up, so if a page is less than a screenful, it has 64 px of white space at the bottom to scroll through. The web views are in a vertical UIPageViewController, so this disrupts paging. Is there some way to get rid of this extra space?
Have you tried something like adjusting the webview's scrollview content insets? Example:
webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0,64, 0)
It sounds like what you need is to adjust the webView.scrollView.contentSize and adjust the height by 64. You may need to provide more information about how it slides behind the nav bar and status bar to help me answer this. I would take a look at this section of the Scroll View Programming Guide:
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/UIScrollView_pg/CreatingBasicScrollViews/CreatingBasicScrollViews.html
Change the clipsToBounds.
webView.clipsToBounds = NO;
This will make its content visible outside its frame, so set its frame like normal, right under the navigation bar. The navigation bar will be translucent and you will see its content under it.
Don't forget to disable Autolayout for the web view!
I've sort of made an end-run around this problem by disabling scrolling on short pages. Basically, I use -stringByEvaluatingJavaScriptFromString: to run some JavaScript inside the page that walks down from document.body and computes the position of the bottom of the bottommost element. (document.body itself is always at least as large as the viewport, so I can't look at its size.) Then, back in Objective-C-land, I compare that to the height of the web view (less the inset), and if it's less, I disable scrolling. This is not a perfect solution, but it covers the worst symptoms.
If someone can come up with a better solution than this, I'd love to hear about it! Either way, I can't award the bounty to myself, so someone will be getting it.

iOS: How do I keep the UIToolbar (that I've added to UIWebView.scrollView) from going off screen?

Hopefully i can explain this clearly. I have a UIWebView and I've added a UIToolbar to it's scrollView (another works [webView.scrollView addSubview:myToolbar];). So everything is fine and dandy until i try to pinch zoom that's when the toolbar stays in the corner of the screen, so basically it doesn't stay in the middle. If you haven't guessed already, I'm trying to make a duplicate of safari's behavior. I need to have the UIToolbar to not be affected by the pinch gesture. Any ideas on how to do this? I've read other posts but it doesn't seem to really give an answer. Any help is appreciated :)
You have to create a parent UIView, say rootV, in which you embed myToolbar at the top, and then webView.
This stops the pinching from affecting myToolbar, however this make it stick at the top, and not move beyond the screen when the user scrolls vertically myWebView.
To get the same behavior as Safari, you have to check the vertical scrolling in myWebView, and based on it you expand up or down the size of rootV. Assuming you fixed the height of myToolbar but made webView fill the rest, it should just work.

Resources