I have a horizontal UIScrollView with paging. There are two buttons. One scrolls scrollView to the left another to the right.
The code for the left one:
- (IBAction)goLeftAction:(id)sender
{
CGFloat pageWidth = _theScrollView.frame.size.width;
int page = floor((_theScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
if(page>0){
page -=1;
[_theScrollView scrollRectToVisible:CGRectMake(_theScrollView.frame.size.width*page, 0, self.view.frame.size.width, self.view.frame.size.height) animated:YES];
}
}
I want button to make scrollView show a bouncing effect when we are at the first page (page=0) and push LEFT.
Please help find the way to achieve this.
EDIT:
Here is the code if someone need it.
First I added to goLeftAction:
[_theScrollView setPagingEnabled:NO];
[_theScrollView setScrollEnabled:NO];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(bounceScrollView) userInfo:nil repeats:NO];
And this next:
- (void)bounceScrollView
{
[self.theScrollView scrollRectToVisible:CGRectMake(100, 0, self.view.frame.size.width, self.view.frame.size.height) animated:YES];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(unbounceScrollView) userInfo:nil repeats:NO];
}
- (void)unbounceScrollView
{
[self.theScrollView scrollRectToVisible:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) animated:YES];
[_theScrollView setPagingEnabled:YES];
[_theScrollView setScrollEnabled:YES];
}
This is an interesting question. Have you seen this similar question on SO? It bounces vertically, not horizontally, but the concept is the same.
Set pagingEnabled and scrollEnabled to NO
Animate bounce using scrollRectToVisible:animated:
Set pagingEnabled and scrollEnabled back to YES
This discussion also has some sample code that may be useful.
EDIT:
I had a play around with the code in your edit above, and managed to get the bounce working in the correct direction. I had to use setContentOffset:animated: instead of scrollRectToVisible:animated:, and I also increased the timer interval to 0.3 (0.1 is not enough time for the bounce to reach the full distance before unbounceScrollView is called).
My code in goLeftAction::
[self.scrollView setPagingEnabled:NO];
[self.scrollView setScrollEnabled:NO];
[NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:#selector(bounceScrollView) userInfo:nil repeats:NO];
The bounce methods:
- (void)bounceScrollView
{
[self.scrollView setContentOffset:CGPointMake(-100, 0) animated:YES];
[NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:#selector(unbounceScrollView) userInfo:nil repeats:NO];
}
- (void)unbounceScrollView
{
[self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
[self.scrollView setPagingEnabled:YES];
[self.scrollView setScrollEnabled:YES];
}
Related
I have made a view on another view and make a movable label form right to left, problem is that label moves on whole view and i want to show it only on second view not on mainview.. how to hide that label from particular view??
here is my code
- (void)viewDidLoad {
[super viewDidLoad];
self.movelabel = [[UILabel alloc]initWithFrame:CGRectMake(200, 0, 200, 30)];
self.movelabel.text = #"This is my music line";
[self.moveview addSubview:self.move];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(LabelAnimation) userInfo:nil repeats:YES];
}
-(void)LabelAnimation
{
[UIView animateWithDuration:3.0f delay:0.0f options:UIViewAnimationOptionTransitionNone animations:^{
self.move.frame = CGRectMake(-200, 0, 200, 60);
} completion:^(BOOL finished)
{
self.move.frame = CGRectMake(200, 0, 200, 60);
}];
}
Thankyou.
If self.move is label then set clipsToBounds property of its superview to yes
i.e
self.move.superview.clipsToBounds = YES;
It will clip if self.move goes out of bounds of its superview.
Hope it helps :)
to hide UILabel
use :-
yourLbl.hidden = YES;
[yourLbl setHidden:YES];
or to remove
[yourLbl removeFromSuperview];
hope it may help you.
I am using NSTimer to move through my UIScrollview, but I can't get to make it stop at every page for like let's say a second or two so users can be able to preview and click if they want to or when they are scrolling around the images in the UIScrollview my Code is below....:
-(void) onTimer {
CGPoint rightOffset = CGPointMake(responseScroll.contentSize.width - responseScroll.bounds.size.width, 0);
[responseScroll setContentOffset:rightOffset animated:YES];
}
-(void)viewDidLoad {
/-------/
[NSTimer scheduledTimerWithTimeInterval:0.008 target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
}
Make the timer interval 2.0:
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
This means that the timer will fire every 2 seconds.
If you want to shift one page over, you need to adjust your onTimer method:
CGPoint rightOffset = CGPointMake(responseScroll.contentOffset.x + responseScroll.frame.size.width, 0);
[responseScroll setContentOffset:rightOffset animated:YES];
Consider using UIAnimations instead
-(void)viewDidLoad{
[self moveScrollView];
}
-(void)moveScrollView{
CGPoint rightOffset = CGPointMake(responseScroll.contentOffset.x+responseScroll.bounds.size.width, 0);
if(rightOffset.x+responseScroll.bounds.size.width<=responseScroll.contentSize.width){
[UIView animateWithDuration:1 animations:^{
[responseScroll setContentOffset:rightOffset animated:NO];
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self moveScrollView];
});
}];
}
}
Here is my answer, this is in swift. This will scroll the pages in scrollview infinitely.
private func startBannerSlideShow()
{
UIView.animate(withDuration: 6, delay: 0.1, options: .allowUserInteraction, animations: {
scrollviewOutlt.contentOffset.x = (scrollviewOutlt.contentOffset.x == scrollviewOutlt.bounds.width*2) ? 0 : scrollviewOutlt.contentOffset.x+scrollviewOutlt.bounds.width
}, completion: { (status) in
self.startBannerSlideShow()
})
}
I am stuck in something I hope you guys can help
I have a scrollview , when the user scrolling a subview appear with animation from bottom to top. the timer then start counting 5 sec and then call another method to hide the subview
I implemented and it works as wanted except :
while the subview appear and when it's almost to hide , if I scrolled that moment the subview appear statically and never hide . try to scrolling again another subview dynamically work over the static one ( as it duplicated or something)
this is my code for controlling show and hide of subview
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(!show){
[self showSubview];
if (!myidleTimer)
[self resetIdleTimer];
}
}
-(void)resetIdleTimer
{
//convert the wait period into minutes rather than seconds
int timeout = kApplicationTimeoutInMinutes;// equal to 5 seconds
[myidleTimer invalidate];
myidleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout target:self selector:#selector(idleTimerExceeded) userInfo:nil repeats:NO];
}
-(void)idleTimerExceeded
{
if (show){
[myidleTimer invalidate];
[self hideSubview];
show=false;
}
}
"show" is a bool to insure when to hide and when to show
her is the show / hide implementation
-(void)hideSubview{
[UIView animateWithDuration:0.5
animations:^{
subview.frame = CGRectMake(0, screenWidth, screenHeight, 60);//move it out of screen
} completion:^(BOOL finished) {
[subview removeFromSuperview];
subview.frame=CGRectMake(0,screenWidth, screenHeight, 0);
}];
show=false;
}
-(void) showSubview{
subview = [[UIView alloc] init ];
[self.view addSubview:subview];
subview.frame = CGRectMake(0, screenWidth, screenHeight, 60);
[UIView animateWithDuration:1.0
animations:^{
subview.frame = CGRectMake(0, screenWidth-60, screenHeight, 60);
}];
show=TRUE;
}
I hope that's clear enough to understand and be able to help me identify the problem
thanks in advance
The timer will not fire while the scroll view is being scrolled, if you create the timer the way you do. Instead, create it as below.
NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:#selector(doStuff:) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: adds the timer to the run loop using the defaultRunLoopMode instead of the NSRunLoopCommonModes, which is the one you want to have timer fire while the user scrolls.
I'm developing an app with a scroll view in it. It's not immediately obvious that there's more content, and there's no scroll indicator (scroll view is paged).
So, to give the user a 'hey, there's something down here...', I would like to have the scroll view do a subtle bounce - down then up - on launch. I've tried this:
- (void)viewDidLoad
....
[NSTimer scheduledTimerWithTimeInterval:0.8 target:self selector:#selector(bounceScrollView) userInfo:nil repeats:NO];
}
- (void)bounceScrollView
{
[self.verticalScrollViews[0] scrollRectToVisible:CGRectMake(0, 600, 1, 1) animated:YES];
[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(_unbounceScrollView) userInfo:nil repeats:NO];
}
- (void)_unbounceScrollView
{
[self.verticalScrollViews[0] scrollRectToVisible:CGRectZero animated:YES];
}
However, this code makes the view get 'stuck' at about halfway between two pages.
Any help?
Idea 1: You need to turn off paging, animate the bounce, and turn the paging back on.
Idea 2: Your second move is coming way too soon:
scheduledTimerWithTimeInterval:0.01
Experiment with longer time intervals! I would start with 0.4.
Idea 3: Instead of your bounce, why not use flashScrollIndicators? This is exactly what it is for!
I had a memory problems when using NSTimer. That's why I used another solution for scrollView preview.
[UIView animateWithDuration:1.0
delay:0.00
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
_scrollView.contentOffset = CGPointMake(200,0);
}
completion:^(BOOL finished){
[UIView animateWithDuration:1.0
delay:0.00
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
_scrollView.contentOffset = CGPointMake(0,0);
}
completion:^(BOOL finished){
}
];
}
];
I am using the following code in order to create a UIScrollView:
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scroll.pagingEnabled = YES;
NSInteger numberOfViews = 3;
for (int i = 0; i < numberOfViews; i++) {
CGFloat yOrigin = i * self.view.frame.size.width;
UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(yOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
awesomeView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5 blue:0.5 alpha:1];
[scroll addSubview:awesomeView];
}
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
[self.view addSubview:scroll];
The Question is: How do I implement an NSTimer in order to change the page every 4 seconds?
[NSTimer scheduledTimerWithTimeInterval:4.0f
target:self
selector:#selector(updateCounter:)
userInfo:nil
repeats:YES];
I am struggling to write the updateCounter method. Please help
- (void)updateCounter:(NSTimer *)theTimer {
NSInteger numberOfViews = 3;
int i = 0; i++;
if (i < numberOfViews) {
yOrigin = i * self.view.frame.size.width;
[scroll scrollRectToVisible:CGRectMake(yOrigin, 0, self.view.frame.size.width, self.view.frame.size.height) animated:YES];
}
return; }
OK, so with this code, NSTimer changes from view 1 to view 2, but it stops, it does not change after the next 4 seconds to view 3. What I want to do is to change from view 1, to view 2, after 4 seconds, then to view 3, after 4 seconds, and so on. I want to have as many views as I need.
you are doing everything right. Now you need to implement updateCounter so that the scroll of the scrollView happens automatically. maintain global width counter. Keep updating this counter in every call to updateCounter. You could do this like so -
int global_width = self.view.frame.size.width;
int global_height = self.view.frame.size.height;
- (void) updateCounter
{
int width = (global_width%self.view.frame.size.width)*self.view.frame.size.width;
[yourScrollView scrollRectToVisible:CGRectMake(0, 0, width, global_height) animated:YES];
global_width += self.view.frame.size.width;
return;
}
This way you keep cycling between the pages automatically. Hoep this works, all of it is typed freehand. But the concept is correct.
If you want to update a counter every four seconds, call your updateCounter method this way:
[NSTimer scheduledTimerWithTimeInterval:4.0f
target:self
selector:#selector(updateCounter)
userInfo:nil
repeats:YES];
There's two differences in what you did. #1, the time interval is 4 seconds. #2, if you don't have any parameters going into the updateCounter method, don't append a colon to the selector.
And then your updateCounter method:
- (void) updateCounter
{
// what view are you modifying?
// the content view or a subview within the ScrollView's contentView ?
}