Skip to content

Commit

Permalink
[TIMOB-24963] iOS/Android: Added new ScrollView.scrollToTop() method (#…
Browse files Browse the repository at this point in the history
…9601)

* scrollToTop()

* [TIMOB-24963] Add iOS-parity, update docs

* set to version 7

* Android/iOS/Windows: Added unit test for ScrollView.scrollToTop() function.

* Android: Fixed animated scrolling issues in ScrollView.

- [TIMOB-25514] Fixed bug where vertical ScrollView.scrollTo() goes to wrong position when animated. (Introduced in 6.2.2.)
- [TIMOB-25515] Fixed bug where ScrollView.scrollTo() ignores "ti.ui.defaultunit" when animated.
- Fixed ScrollView.scrollToTop() method for vertical scroll views for TIMOB-24963.
  * This bug was never introduced into Titanium. It was caught before the pull request was merged.
  * Caused by bug in Google's NestedScrollView which Titanium switched to in 6.2.2.

* iOS: Reverted "TiUIScrollViewProxy.h" changes made by TIMOB-24963.

- Restored code formatting back to Axway Appcelerator coding standards.

* Move test addition to addontest
  • Loading branch information
jquick-axway authored and sgtcoolguy committed Nov 15, 2017
1 parent 831da45 commit faff14a
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class ScrollViewProxy extends TiViewProxy

private static final int MSG_SCROLL_TO = MSG_FIRST_ID + 100;
private static final int MSG_SCROLL_TO_BOTTOM = MSG_FIRST_ID + 101;
private static final int MSG_SCROLL_TO_TOP = MSG_FIRST_ID + 102;
protected static final int MSG_LAST_ID = MSG_FIRST_ID + 999;

public ScrollViewProxy()
Expand Down Expand Up @@ -99,6 +100,15 @@ public void scrollToBottom() {
}
}

@Kroll.method
public void scrollToTop() {
if (!TiApplication.isUIThread()) {
TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_SCROLL_TO_TOP), getActivity());
} else {
handleScrollToTop();
}
}

@Override
public boolean handleMessage(Message msg) {
if (msg.what == MSG_SCROLL_TO) {
Expand All @@ -112,6 +122,11 @@ public boolean handleMessage(Message msg) {
AsyncResult result = (AsyncResult) msg.obj;
result.setResult(null); // signal scrolled
return true;
} else if (msg.what == MSG_SCROLL_TO_TOP) {
handleScrollToTop();
AsyncResult result = (AsyncResult) msg.obj;
result.setResult(null); // signal scrolled
return true;
}
return super.handleMessage(msg);
}
Expand All @@ -124,6 +139,10 @@ public void handleScrollToBottom() {
getScrollView().scrollToBottom();
}

public void handleScrollToTop() {
getScrollView().scrollToTop();
}

@Override
public String getApiName()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -862,17 +862,34 @@ public boolean getScrollingEnabled()

public void scrollTo(int x, int y, boolean smoothScroll)
{
// Fetch the scroll view.
final View view = this.scrollView;
if (view == null) {
return;
}

// Convert the given coordinates to pixels.
x = TiConvert.toTiDimension(x, -1).getAsPixels(view);
y = TiConvert.toTiDimension(y, -1).getAsPixels(view);

// Disable smooth scrolling for vertical scroll views if not at top of view.
// Note: This works-around a bug in Google's NestedScrollView where attempting to
// smooth scrolls will move to a totally different position or opposite directions.
if (smoothScroll && (view instanceof TiVerticalScrollView)) {
if (((TiVerticalScrollView)view).getScrollY() > 0) {
smoothScroll = false;
}
}

// Scroll to the given position.
if (smoothScroll) {
if (view instanceof TiHorizontalScrollView) {
TiHorizontalScrollView scrollView = (TiHorizontalScrollView) view;
scrollView.smoothScrollTo(x, y);
((TiHorizontalScrollView)view).smoothScrollTo(x, y);
} else if (view instanceof TiVerticalScrollView) {
TiVerticalScrollView scrollView = (TiVerticalScrollView) view;
scrollView.smoothScrollTo(x, y);
((TiVerticalScrollView)view).smoothScrollTo(x, y);
}
} else {
view.scrollTo(TiConvert.toTiDimension(x, -1).getAsPixels(view), TiConvert.toTiDimension(y, -1).getAsPixels(view));
view.scrollTo(x, y);
}
view.computeScroll();
}
Expand All @@ -881,9 +898,30 @@ public void scrollToBottom()
{
View view = this.scrollView;
if (view instanceof TiHorizontalScrollView) {
((TiHorizontalScrollView)this.scrollView).fullScroll(View.FOCUS_RIGHT);
((TiHorizontalScrollView)view).fullScroll(View.FOCUS_RIGHT);
} else if (view instanceof TiVerticalScrollView) {
((TiVerticalScrollView)this.scrollView).fullScroll(View.FOCUS_DOWN);
((TiVerticalScrollView)view).fullScroll(View.FOCUS_DOWN);
}
}

public void scrollToTop()
{
View view = this.scrollView;
if (view instanceof TiHorizontalScrollView) {
// Scroll to the left-most side of the horizontal scroll view.
((TiHorizontalScrollView)view).fullScroll(View.FOCUS_LEFT);
} else if (view instanceof TiVerticalScrollView) {
// Scroll to the top of the vertical scroll view.
// Note: There is a bug in Google's NestedScrollView where smooth scrolling to top fails
// and can scroll down instead. We must work-around it by temporarily disabling it.
TiVerticalScrollView verticalScrollView = (TiVerticalScrollView)view;
boolean wasEnabled = verticalScrollView.isSmoothScrollingEnabled();
verticalScrollView.setSmoothScrollingEnabled(false);
try {
((TiVerticalScrollView)view).fullScroll(View.FOCUS_UP);
} finally {
verticalScrollView.setSmoothScrollingEnabled(wasEnabled);
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions apidoc/Titanium/UI/ScrollView.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@ methods:
platforms: [android, iphone, ipad]
since: {iphone: "2.1.0", ipad: "2.1.0"}

- name: scrollToTop
summary: Moves the top of the scrollable region into the viewable area.
description: |
On Android the behavior of `scrollToTop` depends on whether this scroll view scrolls
horizontally or vertically. For vertical scroll views, `scrollToTop` moves the top
of the scrollable region into the viewable area. For horizontal scroll views,
`scrollToTop` moves the leftmost edge of of the scrollable region into the viewable area.
On iOS, `scrollToTop` moves the top-left corner of the scrollable region into the
viewable area.
platforms: [iphone, ipad, android]
since: "7.0.0"

events:
- name: scale
summary: Fired when the zoom scale factor changes.
Expand Down
1 change: 1 addition & 0 deletions iphone/Classes/TiUIScrollView.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
- (UIView *)wrapperView;
#endif
- (void)scrollToBottom;
- (void)scrollToTop;

@end

Expand Down
5 changes: 5 additions & 0 deletions iphone/Classes/TiUIScrollView.m
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,11 @@ - (void)scrollToBottom
[currScrollView setContentOffset:newOffset animated:YES];
}

- (void)scrollToTop
{
[[self scrollView] setContentOffset:CGPointMake(0, -[[self scrollView] contentInset].top) animated:YES];
}

- (void)setDecelerationRate_:(id)value
{
[self.proxy replaceValue:value forKey:@"decelerationRate" notification:NO];
Expand Down
10 changes: 9 additions & 1 deletion iphone/Classes/TiUIScrollViewProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -330,14 +330,22 @@ - (void)scrollTo:(id)args
[offset release];
}

- (void)scrollToBottom:(id)args
- (void)scrollToBottom:(id)unused
{
TiThreadPerformOnMainThread(^{
[(TiUIScrollView *)[self view] scrollToBottom];
},
YES);
}

- (void)scrollToTop:(id)unused
{
TiThreadPerformOnMainThread(^{
[(TiUIScrollView *)[self view] scrollToTop];
},
YES);
}

- (void)setContentOffset:(id)value withObject:(id)animated
{
TiThreadPerformOnMainThread(^{
Expand Down
18 changes: 18 additions & 0 deletions tests/Resources/ti.ui.scrollview.addontest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Appcelerator Titanium Mobile
* Copyright (c) 2011-Present by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
/* eslint-env mocha */
/* global Ti */
/* eslint no-unused-expressions: "off" */
'use strict';
var should = require('./utilities/assertions');

describe('Titanium.UI.ScrollView', function () {
it('#scrollToTop()', function () {
var bar = Ti.UI.createScrollView({});
should(bar.scrollToTop).be.a.Function;
});
});

0 comments on commit faff14a

Please sign in to comment.