Open aleqs opened 11 years ago
There are already methods to do this:
scrollOffset is a readwrite property, so you can set it and the carousel will scroll to position immediately without an animation.
There is also the following method to animation the scroll:
- (void)scrollToOffset:(CGFloat)offset duration:(NSTimeInterval)duration;
Currently this is not true. Perhaps you intended it to work differently, but your implementation implicitly uses the scrollOffset property instead of using the _ scrollOffset variable in case of duration == 0.0, which causes the timer to be created and the change to take effect only after the timer triggers step method first time
- (void)scrollByOffset:(CGFloat)offset duration:(NSTimeInterval)duration {
if (duration > 0.0) {
_decelerating = NO;
_scrolling = YES;
_startTime = CACurrentMediaTime();
_startOffset = _scrollOffset;
_scrollDuration = duration;
_previousItemIndex = roundf(_scrollOffset);
_endOffset = _startOffset + offset;
if (!_wrapEnabled) {
_endOffset = [self clampedOffset:_endOffset];
}
if ([_delegate respondsToSelector:@selector(carouselWillBeginScrollingAnimation:)]) {
[_delegate carouselWillBeginScrollingAnimation:self];
}
[self startAnimation];
}
else {
self.scrollOffset += offset;
}
}
The scrollOffset property doesn't invoke the timer, it sets the _scrollOffset immediately using the same logic as your setScrollOffset:animated: method:
- (void)setScrollOffset:(CGFloat)scrollOffset
{
if (_scrollOffset != scrollOffset)
{
_scrolling = NO;
_decelerating = NO;
[self disableAnimation];
_scrollOffset = [self clampedOffset:scrollOffset];
[self didScroll];
_previousItemIndex = self.currentItemIndex;
[self depthSortViews];
[self enableAnimation];
}
}
yes it does :) setScrollOffset invokes didScroll which in turn calls startAnimation, and all the changes are then performed in step method
- (void)didScroll {
...
if (difference) {
_toggleTime = CACurrentMediaTime();
_toggle = fmaxf(-1.0f, fminf(1.0f, -(CGFloat) difference));
#ifdef ICAROUSEL_MACOS
if (_vertical)
{
//invert toggle
_toggle = -_toggle;
}
#endif
[self startAnimation];
}
...
}
On a separate note, I want to say thank you for this awesome library. I totally love it and like the fact that you are so quick to respond. It gives me pleasure to participate in improving it
I think you misunderstand the purpose of starting the timer in didScroll. It's is not to move the carousel to the specified offset, it is to so that the carousel can auto-correct if it has been misaligned.
I just checked and this is working as intended. In the tests folder of iCarousel there is a project called "Scrolling". Open that project, and run it. When you press the button, the carousel jumps to a particular point and then smoothly aligns to the nearest integer offset.
If you modify this function:
- (void)reloadAndScroll
{
[carousel reloadData];
[carousel scrollByOffset:4.5 duration:0.0];
}
To this:
- (void)reloadAndScroll
{
carousel.scrollOffset += 4;
}
Now run it and press the button a few times. Notice that the carousel snaps instantly into position and doesn't animate?
It will still run the timer for a single step afterwards, but you can completely disable the timer by commenting out the body of the startAnimation method and it will still work exactly the same way.
If you are trying to disable the auto-align behaviour when scrollOffset is set to a non-integer value, you can do that by setting carousel.scrollToItemBoundary = NO;
And you're welcome - I'm glad you like iCarousel :-)
Yes good point thanks
The reason I asked this is I have a table view with nested iCarousel items in each table cell. When a user scrolls through table view, I want to set iCarousel offset so that a specific item be presented by default. However, despite the scrollOffset value being propagated correctly in cellForRowAtIndexPath method, I have a visual artefact of iCarousel first appearing with the state where the cell was left off, and only after a couple of seconds adjusting to the offset I set. After having another look, I can conclude that iCarousel is rendered stuck in the previous state while table view scrolling animation is running. When I scroll through the table view and see this artefact, it's all gone once animation stops or when I release the mouse
I thought I found a solution when posting this issue, but as you pointed out I didn't quite understand the purpose of didScroll method, so just targeted it to avoid animation. So I ran my modified code again, only to find that the issue I was fighting with is still there
Hi,
I implemented this feature locally so thought you might find it useful and include in iCarousel. The version I'm using is master@1.7.4
Sometimes when using carousel, I want to completely bypass the timer and have the scroll offset change to take effect immediately. So I created a version of setScrollOffset and didScroll methods that accept animated flag and placed setScrollOffset:animated to the h file:
m file:
...