My project needs to add and delete a uiwebview to uiscrollview at runtime. Means, when we scroll it horizontally (left or right) when paging is enabled, then a new view get added to the uiscrollview and it traverse to it.
Is it possible to detect the left or right scrolling in uiscrollview?
Plz tell me the best possible solution, sample code or any tutorial.
Thanks in advance
In such cases, we should have paging enabled in our scroll view.
Lets say you have scroll view of size 320x480, and it is supposed to show 10 pages, where size of each page is 320x480, making content size of scroll view as 320*10 x 480.
The best way to determine the current page is by using the content offset value of the scroll view.
So, in the beginning, when scrollview is showing 1st page, its content offset would be x=0, y=0.
For 2nd page x=320, y=0.
Thus we can get the current page value by dividing the contentOffset.x by page-width.
Thus, 0/320 = 0, means 1st page. 320/320 = 1, means 2nd page, and so on.
Thus, if we have current page value with us, we can determine in which direction the scroll view is moving, as follows:
-(void) scrollViewDidScroll:(UIScrollView *)scrollView{
int currentPageOffset = currentPage * PAGE_WIDTH;
if (self.pageScrollView.contentOffset.x >= currentPageOffset + PAGE_WIDTH) {
// Scroll in right direction. Reached the next page offset.
// Settings for loading the next page.
currentPage = self.pageScrollView.contentOffset.x/PAGE_WIDTH;
}else if (self.pageScrollView.contentOffset.x <= currentPageOffset - PAGE_WIDTH) {
// Scroll in left direction. Reached the previous page offset.
// Setting for loading the previous page.
currentPage = self.pageScrollView.contentOffset.x/PAGE_WIDTH;
}
}
Related
Anyone knows automation script to verify a view (homePage/Browse) is scrollable or not. i can use ScrollTo(id) which is at the bottom of the page. But it is not a correct method to do, as test case passes if that element present in 1st page
Basically You cannot. You could try to cast the view to ScrollView class however any custom view can implement scroll.
Get the coordinates of any particular element like button etc unique element.
Swipe using driver.swipe() to 100 or more pixels.
And get the coordinates of that element again and check whether x or y coordinates changed or not.
This will let you know whether it is a single page application or more to scroll.
Basically there is no API to check the view is scrollable or not but if you still require this then you can do work around
#Test
public void testVerticalScroll()
{
//Try to Scroll till the 15th row
driver.scrollTo("List item:15");
//Assert that the 1st row is not visible.
Assert.assertFalse( driver.findElement(By.name("List item:01")).isDiaplyes())
//Assert that the 15th row is not visible.
Assert.assertTrue( driver.findElement(By.name("List item:15")).isDiaplyes())
}
You can consider the last visible element as "YourText" But this is
just a workaround that needs to be customized for each page.
Here we are using swipe until we find the element. In this case, the last visible element indicates the margin of the page.
Dimension dimensions = driver.manage().window().getSize();
Double screenHeightStart = dimensions.getHeight() * 0.5;
int scrollStart = screenHeightStart.intValue();
System.out.println("s="+scrollStart);
Double screenHeightEnd = dimensions.getHeight() * 0.2;
int scrollEnd = screenHeightEnd.intValue();
for (int i = 0; i < dimensions.getHeight(); i++) {
driver.swipe(0,scrollStart,0,scrollEnd,2000);
if (driver.findElement(By.name("YourText")).size()>0)
exit;
}
driver.findElement(By.name("YourText")).click();
There is a way to check it. You have to find a layer that you will target for example:
MobileElement scrollableLayer= driver.findElementById("elementID");
Then you will extract attribute value "scrollable" of that element like this:
String scrollableState = scrollableLayer.getAttribute("scrollable");
And then you can check if the String value is true or false.
if (scrollableState.equals("true")){System.out.println("it's scrolable"); }else{System.out.println("it's not scrolable");}
Or you can do whatever you want with it :)
I use scrollviewer in my windows store application, but after calling SetHorizontalOffset function some times scrollviewer doesn't change horizontal scrolling. The same thing with vertical scrolling. Does anybody know how to work with it? May be scrollviewer scroll only for visibility for offset (I mean that if it's see that user can see offset its doesn't scroll at all)
It appears the ScrollViewer's offset lags by one frame.
If the below code is run every frame, diffPrevDesiredActual is always 0. That is to say, the value provided by ChangeView does not take affect immediately.
...
var scrollPosition = /*some new value*/;
MyScrollViewer.ChangeView(null, scrollPosition, null, true);
var current = MyScrollViewer.VerticalOffset;
var diffDesiredActual = scrollPosition - current;
var diffPrevDesiredActual = previous - current;
previous = scrollPosition;
...
private double previous;
If nothing on your screen is animating when you change the scroll offset, then it is possible the ScrollViewer won't show the new value until something triggers the draw of a new frame. To test this hypothesis, try adding an infinite animation (eg ProgressRing) to ensure frames are constantly being drawn.
I have a responsive layout and I am using sticky.js for my header. This seems to be working minus a few glitches that I can live with. But my anchors are always off (I am using smooth scrolling). I am not sure how to compensate for the sticky header when scrolling to an anchor when the responsive layout is constantly changing the width and height?
Unfortunately there is not a whole lot you can do with straight-CSS which won't distort your design. To tackle this issue in previous projects, I have used jQuery to handle these types of scrolling/anchor issues.
What You Have Now: <a> tags that look for id's on the page. The problem is this: when the site goes responsive, those anchor tags don't line up so nicely with your DOM layout.
My Solution: To give you the high level concept - I used jQuery to modify the ID positions on the fly. Say you click on a link when the site is full-size, and everything is fine. jQuery is not needed here. Now say that when you click that same link when the site was scaled to about the 768px-width range (iPad portrait): then my anchors might look as if they were about 100px off (for example). I wrote a bit of jQuery to handle this: "If the width is __, then offset the anchor ID's by ___px."
I would recommend using JS to account for the difference at time-of-scroll, rather than trying to artificially alter the height property of your anchor tags. Here's a function that might work for you, using pure JS:
adjustScroll = function () {
// Sticky nav selector (you'll have to provide your own selector)
const nav = document.querySelector('header>nav');
if (location.href.indexOf("#") >= 0) {
// Find the name of the anchor
let n = location.href.substr(location.href.indexOf("#")+1);
// Find the anchor by name, if it exists
let a = document.querySelector('a[name="'+n+'"]');
if (!a) {
return;
}
// Set y value as y-value of the anchor, offset by the header height
let y = a.offsetTop;
y -= nav.height + 10;
// Scroll to the y position
window.scrollTo(0, y);
}
}
// Call it wherever you need to call it
adjustScroll();
Examples of where to call it might be on a DOMContentLoaded event, or on an onclick event for anchor tags.
I am trying to imitate what Apple has when showing the search result in the App Store. (reference: http://searchengineland.com/apple-app-search-shows-only-one-result-at-a-time-133818)
It shows like the detailed-application-info in a cards and it is paged. I am stuck at how to make the previous-and-next card shows when one active card in the middle and the scroll view's paging behaviour is still intact.
I have tried using the UICollectionView and set the clipSubviews to NO, hoping that it will show the previous page and the next page, but as soon as the cell goes off-screen, the cell gets hidden (removed from the view hierarchy) and not displayed. I think thats the flyweight pattern of the UICollectionView (the behavior of UICollectionView). Any ideas of what would be possible?
Cheers,
Rendy Pranata
The problem: UICollectionView as a subclass of UIScrollView essentially animates its bounds by a stride of bounds.size. Although this could mean that all you had to do is decrease the bounds while keeping the frame bigger, unfortunately UICollectionView will not render any cells outside its current bounds... destroying your preview effect.
The Solution:
Create a UICollectionView with paging set to NO and with the desired frame.
Create UICollectionViewCells that are smaller than the UICollectionView's frame/bounds. At this stage, a part of the next cell should show in the frame. This should be visible before implementing the other steps below.
Add a collectionView.contentInset.left and right (I assume your layout is horizontal) equal to the contentOffsetValue method (as shown below for simplicity) so as to align the first and last cells to the middle.
Create a UICollectionViewFlowLayout which overrides the method that gives the stopping point like so:
Like so:
-(CGFloat)contentOffsetValue
{
return self.collectionView.bounds.size.width * 0.5f - self.itemSize.width * 0.5f;
}
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
static float EscapeVelocity = 0.5f; // otherwise snap back to the middle
NSArray* layoutAttributesArray = [self layoutAttributesForElementsInRect:self.collectionView.bounds];
if(layoutAttributesArray.count == 0)
return proposedContentOffset;
CGFloat currentBoundsCenterX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width * 0.5f;
UICollectionViewLayoutAttributes* candidateNextLayoutAttributes = layoutAttributesArray.firstObject;
for (UICollectionViewLayoutAttributes* layoutAttributes in layoutAttributesArray)
{
if ((layoutAttributes.representedElementCategory != UICollectionElementCategoryCell) ||
(layoutAttributes == candidateNextLayoutAttributes)) // skip the first comparison
continue;
if(velocity.x > EscapeVelocity || velocity.x < -(EscapeVelocity))
{
if(velocity.x > EscapeVelocity && layoutAttributes.center.x > candidateNextLayoutAttributes.center.x)
{
candidateNextLayoutAttributes = layoutAttributes;
}
else if (velocity.x < -(EscapeVelocity) && layoutAttributes.center.x < candidateNextLayoutAttributes.center.x)
{
candidateNextLayoutAttributes = layoutAttributes;
}
}
else
{
if(fabsf(currentBoundsCenterX - layoutAttributes.center.x) < fabsf(currentBoundsCenterX - candidateNextLayoutAttributes.center.x))
{
candidateNextLayoutAttributes = layoutAttributes;
}
}
}
return CGPointMake(candidateNextLayoutAttributes.center.x - self.collectionView.bounds.size.width * 0.5f, proposedContentOffset.y);
}
I just put together a sample project which shows how you could do this. I created a container view which is 100 points wider than the 320 points for the screen. Then I put a UICollectionView into that container. This offsets everything by 50 points on both sides of the screen.
Then there is a content cell which simply has a background and a label so you can visually identify what is happening. On the left and right there are empty cells. In the viewDidLoad method the content inset is set to negative values on the left and right to make the empty cells now scroll into view. You can adjust the inset to your preference.
This mimics the behavior fairly closely. To get the label below, like in the example you can simply check the contentOffset value to determine which cell is in focus. To do that you'd use the UIScrollViewDelegate which is a part of UICollectionView.
https://github.com/brennanMKE/Interfaces/tree/master/ListView
You'll notice this sample project has 2 collection views. One is a normal horizontal flow layout while the other one which has larger cells is the one which mimics the example you mentioned.
I am trying to scroll a panel using button tap, and the panel is scrolling as I want. But my problem is that,
After scroll end it back again to its initial position, doesn't stick to its new position.
Why this behavior and how can I get leave from this?
Code I used (working just fine)
var container = this.getDealdetails();
container.getScrollable().getScroller().scrollTo(x , y, true);
The scrollable container will scroll back if the scroll to position is greater than the height of the container.
This is best demonstrated with an example. Run this fiddle: http://www.senchafiddle.com/#8Qnt8
Make your browser window smaller in height and note how it behaves. Hope this makes sense.
var panel= Ext.getCmp('iObserveCreateRecords');
panel.getScrollable().getScroller().scrollTo(0, 0, true);
//iObserveCreateRecords is panel id