I have two concerns to ask.
I would like this scrolling be infinite. I do not want it to stop. I am using iCarousel
My second concern is, while time is passing, scrolling gets
faster with the following code snippet. I would like to keep same speed.
-(void)viewDidAppear:(BOOL)animated
{
[carousel scrollByNumberOfItems:4 duration:20]
}
With the latest version of iCarousel as of January 02, 2015, you could add the following code in your ViewDidLoad method in your Viewcontroller.
- (void)viewDidLoad
{
[super viewDidLoad];
//configure carousel
carousel.type=iCarouselTypeCylinder;
carousel.autoscroll=0.4;
}
Use the autoscroll property instead (just set it to the speed you want)
if u give negative value it moves right to left (the code like this)
- (void)viewDidLoad
{
[super viewDidLoad];
carousel.type=iCarouselTypeCylinder;
carousel.autoscroll= - 0.4;
}
Related
I have implemented a basic slider using iCarousel iOS library but i dont know how to make it as a Auto slider instead of manual swipe sliding.
Here is my sample project code Pls help me
Code
When i searched in google i got this link,but i didnt understand anything
https://github.com/nicklockwood/iCarousel/issues/84
This solved my problem
in ViewDidAppear() i have added following line
-(void)viewDidAppear:(BOOL)animated
{
sliderCount=0;
[super viewDidAppear:animated];
[NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:#selector(runMethod) userInfo:nil repeats:YES];
}
-(void)runMethod
{
[self.carousel scrollToItemAtIndex:sliderCount animated:YES];
if(sliderCount== 7)
{
sliderCount=0;
}
else
{
sliderCount++;
}
}
In your ViewDidLoad method in your Viewcontroller.
- (void)viewDidLoad
{
[super viewDidLoad];
//configure carousel
carousel.type=iCarouselTypeCylinder;
carousel.autoscroll=0.4;
}
Looking at the github link, I assume you want to autoscroll to an item upon view.
You have defined the function
- (void)scrollToItemAtIndex:(NSInteger)index animated:(BOOL)animated
However this isn't part of the iCarousel delegate, its already defined as part of the class, therefore you just need to call it. Putting it in viewDidAppear would seem appropriate if you wanted it to auto scroll to a particular index when your view controller was presented to the user. Simply add the method below.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// The index of 3 was just chosen as an example
NSInteger chosenIndex = 3;
[self.carousel scrollToItemAtIndex:chosenIndex animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
carousel.type=iCarouselTypeCylinder;
carousel.autoscroll=0.8;
[carousel reloadData];
}
I have searched and found multiple posts that the recommended way to determine when a user stopped scrolling, and when a UIScrollView stopped moving is the following:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
// Perform desired outcome here.
NSLog(#"scrollViewDidEndDragging");
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// Perform desired outcome here.
NSLog(#"scrollViewDidEndDecelerating");
}
I have tried multiple ways, I can not get it to work.
Is there something obvious I am missing? Something with the delegate?
Make sure that you have all the following code inside your ViewController.
Under your ViewController.m add
#interface ScrollViewTestViewController ()<UIScrollViewDelegate>
Inside ViewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
self.scrollView1.delegate=self;
self.scrollView2.delegate=self;
}
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView
willDecelerate (BOOL)decelerate {
// Perform desired outcome here.
NSLog(#"scrollViewDidEndDragging");
if(scrollView==self.scrollView1)
//Do Something
else if(scrollView==self.scrollView2)
// Do Another thing
}
Add a Screen Shot and a content size to simulate the scrolling behaviour.
I'm having problems controlling the scrolling within a UITextView that I'm using, so I've opted to create my own subclass.
I've got a very basic question about providing implementations for some of the UIScrollView superclass methods.
Here's my skeleton code for the UITextView subclass:
#interface PastedTextView : UITextView
#end
#implementation PastedTextView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
{
NSLog(#"scrollRectToVisible");
}
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
NSLog(#"setContentOffset");
}
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated
{
NSLog(#"zoomToRect");
}
#end
When will those UIScrollView methods be called? Only from my own client code? Or will they be called by the framework?
Update:
The reason I've asked this is because I'm having the following problem: I'm programatically adding text to the UITextView (from the pasteboard). When I do so, if the textview has scrolled such that the top of the content is no longer in view, the text view scrolls back to the top after the new text has been appended.
I'm not explicitly triggering this scroll, so it's happening within the framework.
I haven't found anything in Apple's documentation that describes this behaviour. So, I've been trying to locate the source of the scrolling so that I can avoid it...
When this scroll happens, none of the above methods are called. Incidentally, neither is UITextViews scrollRangeToVisible method (I've tried adding that method to the subclass implementation). I can't figure out why that implicit scroll back to the top is happening and I want to prevent it...
If you override these UIScrollView methods as shown, any caller (be it your code, or the system's) will hit your implementation instead of the builtin UIScrollView one. If you want to take advantage of the system implementation, you can always call super.
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated
{
[super zoomToRect:rect animated:animated];
NSLog(#"zoomToRect");
}
I have UICollectionView for the user to select images from a grid. Once a cell is selected, the view controller is released, including the UICollectionView.
I'd like to remember where the user was last time they used the UICollectionView and automatically scroll to that location when the view controller is loaded again.
The problem I'm encountering is when this can be done. I'm assuming I need to wait until the UICollectionView has been fully loaded before executing scrollToItemAtIndexPath:atScrollPosition:animated:.
What's the preferred way to determine when the view controller and UICollectionView are fully laid out?
I spent some time exploring solutions. #Leo, I was not able to scroll in viewDidLoad. However, I was able to achieve good results keeping track of the state of the view life cycle.
I created a constant to remember the content offset. I used a constant so it would retain it's value between loads of the VC. I also created a property to flag when it was okay to scroll:
static CGPoint kLastContentOffset;
#property (nonatomic) BOOL autoScroll;
#property (weak, nonatomic) IBOutlet UICollectionView *collection;
The life cycle code I used:
- (void)viewDidLoad
{
[super viewDidLoad];
self.autoScroll = NO; // before CollectionView laid out
}
- (void)viewDidDisappear:(BOOL)animated
{
kLastContentOffset = self.collection.contentOffset;
[super viewDidDisappear:animated];
}
- (void)viewDidLayoutSubviews
{
if (self.autoScroll) { // after CollectionView laid out
self.autoScroll = NO; // don't autoScroll this instantiation of the VC again
if (kLastContentOffset.y) {
[self.collection setContentOffset:kLastContentOffset];
}
}
During the layout of the collectionView I set the flag indicating that the next viewDidLayoutSubviews should auto scroll:
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView
{
self.autoScroll = YES;
// return count here
}
The important part was saving the content offset when my view disappeared. The constant is not remembered between launches of the application which what I wanted and the reason for not saving it in preferences.
Seems like there has to be a more elegant solution but this works well.
I have a UICollectionView that is used to simulate the new calendar in iOS 7. This collection view is inside a controller that has a selectedDate property. Whenever the selectedDate property is set the collection view should scroll to the date in the collection view.
The calendar controller's viewWillAppear also ensure the selected date is visible because this controller is cached and reused.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.calendarView scrollToDate:[self selectedDate] animated:NO];
}
The problem is that the VERY first time the calendar controller is shown the scroll does not work. The contentOffset of the collection view is not updated.
My current workaround is to schedule the scroll to occur on the next run loop using
dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void)
{
// Scroll to the date.
});
It looks like when the UICollectionView is not in a window you cannot scroll. Scheduling the scroll to happen on the next run loop ensure that the view has been added to the window and can be properly scrolled.
Has anyone else experienced this issue and what their workarounds?
you can always force auto-layout to layout.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.view.layoutIfNeeded()
self.collectionView.scrollToItemAtIndexPath......
}
If you are using auto layout, the issue may be that the constraints haven't set the frames yet. Try calling the scrollToDate: method in viewDidLayoutSubviews (without dispatch_after).
#interface CustomViewController ()
#property (nonatomic) BOOL isFirstTimeViewDidLayoutSubviews; // variable name could be re-factored
#property (nonatomic, weak) IBOutlet UIScrollView *scrollView;
#end
#implementation CustomViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.isFirstTimeViewDidLayoutSubviews = YES;
}
- (void)viewDidLayoutSubviews
{
// only after layoutSubviews executes for subviews, do constraints and frames agree (WWDC 2012 video "Best Practices for Mastering Auto Layout")
if (self.isFirstTimeViewDidLayoutSubviews) {
// execute geometry-related code...
// good place to set scroll view's content offset, if its subviews are added dynamically (in code)
self.isFirstTimeViewDidLayoutSubviews = NO;
}
bilobatum's answer is correct!
I'm writing this because I don't have reputation to comment... :/
I tried bilobatum's answer in my project, and it worked perfectly!
My code:
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
if (currentOffset.y != 999) {
[collectionView setContentOffset:currentOffset animated:NO];
}
}
currentOsset is a CGPoint initialized with x = 0 and y = 999 values (CGPoint currentOffset = {0,999};)
In the viewWillDisappear method I save the collectionView's contentOffset in the currentOffset.
This way if I navigate to the controller that has the collectionView and I navigated to there before, I will always have the last position.
The code that will work for you:
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
[self.calendarView scrollToDate:[self selectedDate] animated:NO];
}
Thank you bilobatum for the answer!
Using -viewDidLayoutSubviews created an infinite loop that made the solution too complicated.
Instead I just added a small delay to let the constraints be created before the scrolling:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([self.scheduleDate isThisWeek]) [self.calendarLayout performSelector:#selector(scrollToCurrentTime) withObject:nil afterDelay:1];
}