' +
- '
' +
+ '
' +
'' +
'
' +
'
' +
@@ -77,7 +79,7 @@ IonicModule
'
',
compile: function($element, $attrs) {
if (angular.isUndefined($attrs.pullingIcon)) {
- $attrs.$set('pullingIcon', 'ion-arrow-down-c');
+ $attrs.$set('pullingIcon', 'ion-ios7-arrow-down');
}
if (angular.isUndefined($attrs.refreshingIcon)) {
$attrs.$set('refreshingIcon', 'ion-loading-d');
@@ -88,6 +90,7 @@ IonicModule
pullingText: '@',
refreshingIcon: '@',
refreshingText: '@',
+ disablePullingRotation: '@',
$onRefresh: '&onRefresh',
$onPulling: '&onPulling'
});
diff --git a/js/views/scrollView.js b/js/views/scrollView.js
index b0ab312462..b30333a522 100644
--- a/js/views/scrollView.js
+++ b/js/views/scrollView.js
@@ -687,13 +687,11 @@ ionic.views.Scroll = ionic.views.View.inherit({
self.resetScrollView = function(e) {
//return scrollview to original height once keyboard has hidden
- if(self.isScrolledIntoView) {
- self.isScrolledIntoView = false;
- container.style.height = "";
- container.style.overflow = "";
- self.resize();
- ionic.scroll.isScrolling = false;
- }
+ self.isScrolledIntoView = false;
+ container.style.height = "";
+ container.style.overflow = "";
+ self.resize();
+ ionic.scroll.isScrolling = false;
};
//Broadcasted when keyboard is shown on some platforms.
@@ -1116,8 +1114,6 @@ ionic.views.Scroll = ionic.views.View.inherit({
},
resize: function() {
- if(!this.__container || !this.options) return;
-
// Update Scroller dimensions for changed content
// Add padding to bottom of content
this.setDimensions(
@@ -1286,17 +1282,21 @@ ionic.views.Scroll = ionic.views.View.inherit({
* @param startCallback {Function} Callback to execute to start the real async refresh action. Call {@link #finishPullToRefresh} after finish of refresh.
* @param showCallback {Function} Callback to execute when the refresher should be shown. This is for showing the refresher during a negative scrollTop.
* @param hideCallback {Function} Callback to execute when the refresher should be hidden. This is for hiding the refresher when it's behind the nav bar.
+ * @param tailCallback {Function} Callback to execute just before the refresher returns to it's original state. This is for zooming out the refresher.
*/
- activatePullToRefresh: function(height, activateCallback, deactivateCallback, startCallback, showCallback, hideCallback) {
+ activatePullToRefresh: function(height, activateCallback, deactivateCallback, startCallback, showCallback, hideCallback, tailCallback) {
var self = this;
self.__refreshHeight = height;
- self.__refreshActivate = activateCallback;
- self.__refreshDeactivate = deactivateCallback;
- self.__refreshStart = startCallback;
- self.__refreshShow = showCallback;
- self.__refreshHide = hideCallback;
+ self.__refreshActivate = function(){ionic.requestAnimationFrame(activateCallback);};
+ self.__refreshDeactivate = function(){ionic.requestAnimationFrame(deactivateCallback);};
+ self.__refreshStart = function(){ionic.requestAnimationFrame(startCallback);};
+ self.__refreshShow = function(){ionic.requestAnimationFrame(showCallback);};
+ self.__refreshHide = function(){ionic.requestAnimationFrame(hideCallback);};
+ self.__refreshTail = function(){ionic.requestAnimationFrame(tailCallback);};
+ self.__refreshTailTime = 100;
+ self.__minSpinTime = 600;
},
@@ -1308,6 +1308,9 @@ ionic.views.Scroll = ionic.views.View.inherit({
// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled
this.__publish(this.__scrollLeft, -this.__refreshHeight, this.__zoomLevel, true);
+ var d = new Date();
+ self.refreshStartTime = d.getTime();
+
if (this.__refreshStart) {
this.__refreshStart();
}
@@ -1320,14 +1323,25 @@ ionic.views.Scroll = ionic.views.View.inherit({
finishPullToRefresh: function() {
var self = this;
-
- self.__refreshActive = false;
- if (self.__refreshDeactivate) {
- self.__refreshDeactivate();
+ // delay to make sure the spinner has a chance to spin for a split second before it's dismissed
+ var d = new Date();
+ var delay = 0;
+ if(self.refreshStartTime + self.__minSpinTime > d.getTime()){
+ delay = self.refreshStartTime + self.__minSpinTime - d.getTime();
}
+ setTimeout(function(){
+ if(self.__refreshTail){
+ self.__refreshTail();
+ }
+ setTimeout(function(){
+ self.__refreshActive = false;
+ if (self.__refreshDeactivate) {
+ self.__refreshDeactivate();
+ }
- self.scrollTo(self.__scrollLeft, self.__scrollTop, true);
-
+ self.scrollTo(self.__scrollLeft, self.__scrollTop, true);
+ },self.__refreshTailTime);
+ },delay);
},
@@ -1939,10 +1953,14 @@ ionic.views.Scroll = ionic.views.View.inherit({
// We don't need to normalize scrollLeft, zoomLevel, etc. here because we only y-scrolling when pull-to-refresh is enabled
self.__publish(self.__scrollLeft, -self.__refreshHeight, self.__zoomLevel, true);
+ var d = new Date();
+ self.refreshStartTime = d.getTime();
+
if (self.__refreshStart) {
self.__refreshStart();
}
-
+ // for iOS-ey style scrolling
+ if(!ionic.Platform.isAndroid())self.__startDeceleration();
} else {
if (self.__interruptedAnimation || self.__isDragging) {
@@ -2139,7 +2157,7 @@ ionic.views.Scroll = ionic.views.View.inherit({
self.__minDecelerationScrollTop = 0;
self.__maxDecelerationScrollLeft = self.__maxScrollLeft;
self.__maxDecelerationScrollTop = self.__maxScrollTop;
-
+ if(self.__refreshActive) self.__minDecelerationScrollTop = self.__refreshHeight *-1;
}
// Wrap class method
@@ -2160,11 +2178,11 @@ ionic.views.Scroll = ionic.views.View.inherit({
//Make sure the scroll values are within the boundaries after a bounce,
//not below 0 or above maximum
- if (self.options.bouncing) {
+ if (self.options.bouncing && !self.__refreshActive) {
self.scrollTo(
Math.min( Math.max(self.__scrollLeft, 0), self.__maxScrollLeft ),
Math.min( Math.max(self.__scrollTop, 0), self.__maxScrollTop ),
- false
+ self.__refreshActive
);
}
}
diff --git a/scss/_scaffolding.scss b/scss/_scaffolding.scss
index d490aa5b8f..6a0a35ac65 100644
--- a/scss/_scaffolding.scss
+++ b/scss/_scaffolding.scss
@@ -157,21 +157,21 @@ body.grade-c {
@keyframes refresh-spin {
0% { transform: translate3d(0,0,0) rotate(0); }
- 100% { transform: translate3d(0,0,0) rotate(-180deg); }
+ 100% { transform: translate3d(0,0,0) rotate(180deg); }
}
@-webkit-keyframes refresh-spin {
0% {-webkit-transform: translate3d(0,0,0) rotate(0); }
- 100% {-webkit-transform: translate3d(0,0,0) rotate(-180deg); }
+ 100% {-webkit-transform: translate3d(0,0,0) rotate(180deg); }
}
@keyframes refresh-spin-back {
- 0% { transform: translate3d(0,0,0) rotate(-180deg); }
+ 0% { transform: translate3d(0,0,0) rotate(180deg); }
100% { transform: translate3d(0,0,0) rotate(0); }
}
@-webkit-keyframes refresh-spin-back {
- 0% {-webkit-transform: translate3d(0,0,0) rotate(-180deg); }
+ 0% {-webkit-transform: translate3d(0,0,0) rotate(180deg); }
100% {-webkit-transform: translate3d(0,0,0) rotate(0); }
}
@@ -230,12 +230,16 @@ body.grade-c {
}
&.active {
- .icon-pulling {
+ .icon-pulling:not(.pulling-rotation-disabled) {
@include animation-name(refresh-spin);
-webkit-transform: translate3d(0,0,0) rotate(-180deg);
transform: translate3d(0,0,0) rotate(-180deg);
}
&.refreshing {
+ @include transition(transform .2s);
+ @include transition(-webkit-transform .2s);
+ -webkit-transform: scale(1,1);
+ transform: scale(1,1);
.icon-pulling,
.text-pulling {
display: none;
@@ -244,6 +248,10 @@ body.grade-c {
.text-refreshing {
display: block;
}
+ &.refreshing-tail{
+ -webkit-transform: scale(0,0);
+ transform: scale(0,0);
+ }
}
}
}
diff --git a/test/html/list-simple.html b/test/html/list-simple.html
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/html/pull-to-refresh.html b/test/html/pull-to-refresh.html
new file mode 100644
index 0000000000..daac5e4374
--- /dev/null
+++ b/test/html/pull-to-refresh.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+
Ionic Pull to Refresh
+
+
+
+
+
+
+ Pull To Refresh
+
+
+
+
+
+
+
+ {{item}}
+
+
+
+
+
+
diff --git a/test/unit/angular/directive/refresher.unit.js b/test/unit/angular/directive/refresher.unit.js
index 84e64f7801..975bb3909b 100644
--- a/test/unit/angular/directive/refresher.unit.js
+++ b/test/unit/angular/directive/refresher.unit.js
@@ -70,7 +70,7 @@ describe('ionRefresher directive', function() {
it('should have default pullingIcon', function() {
var el = setup();
- expect(el[0].querySelector('.icon-pulling .ion-arrow-down-c')).toBeTruthy();
+ expect(el[0].querySelector('.icon-pulling .ion-ios7-arrow-down')).toBeTruthy();
});
it('should allow custom pullingIcon', function() {
var el = setup('pulling-icon="super-icon"');
@@ -97,4 +97,8 @@ describe('ionRefresher directive', function() {
expect(el[0].querySelector('.text-refreshing').innerHTML).toBe('5
text');
});
+ it('should allow pulling rotation animation to be disabled', function() {
+ var el = setup('disable-pulling-rotation="true"');
+ expect(el[0].querySelector('.pulling-rotation-disabled').innerHTML).toBeTruthy();
+ });
});