This has been a bit of a interesting one.
So I have a OpenGl screen with a scrollview on top. I Use a CADisplay link to update the render when I scroll (code below) which works really well.
However, I can't get it to snap to a point (animated). I believe the releasing of the CADisplay link stops the animation of the scrollview (see snapToItem).
I tried firing off the release of the CADisplay 2 seconds after but that causes other issues.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
moveFactor = 0 - (((self.scrollView.contentSize.height - self.scrollView.frame.size.height) - self.scrollView.contentOffset.y) / itemScrollViewMoveFactor);
[self updateLabelPositionScale];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self startDisplayLinkIfNeeded];
}
- (void)snapToItem
{
NSLog(#"%d", self.selectItem);
[self.scrollView setContentOffset:CGPointMake(0, (self.scrollView.contentSize.height - self.scrollView.frame.size.height) - (itemScrollViewHeight * self.selectItem)) animated:YES];
//[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(stopDisplayLink) userInfo:nil repeats:NO];
[self stopDisplayLink];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
[self snapToItem];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self snapToItem];
}
#pragma mark Display Link
- (void)startDisplayLinkIfNeeded
{
if (!self.displayLink)
{
self.displayLink = [CADisplayLink displayLinkWithTarget:self.view selector:#selector(display)];
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
}
}
- (void)stopDisplayLink
{
if (self.displayLink)
{
[self.displayLink invalidate];
self.displayLink = nil;
}
}
Did you try adding the display link to NSRunLoopCommonModes?
Related
I have this code:
#pragma mark - UIScrollViewDelegate Methods
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.lastOffsetY = scrollView.contentOffset.y;
}
- (void) scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
if (self.canAnimateBars)
[self animeteBars:scrollView];
}
- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(self.canAnimateBars)
[self animeteBars:scrollView];
}
-(void)animeteBars:(UIScrollView *)scrollView {
bool hide = (scrollView.contentOffset.y > self.lastOffsetY);
[self.view layoutIfNeeded];
if (hide)
self.quickLinkToolBarBotom.constant = -44.0;
else
self.quickLinkToolBarBotom.constant = 0.0;
[[self navigationController] setNavigationBarHidden:hide animated:YES];
}
#pragma mark - UIWebViewDelegate Methods
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.canAnimateBars = YES;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(#"Error: %#", error.localizedDescription);
}
It is working ok, but Would like to archive the same behaviour of the Safari animation.
I have tried this library AMScrollingNavbar but I can't make it work with the Tool Bar.
How can I make the calculations to move the bars while I'm scrolling the Web view like in Safari.
Thanks for the help.
You can use this code. i think this code used for you.
-(void)animeteBars:(UIScrollView *)scrollView {
bool hide = (scrollView.contentOffset.y > self.lastOffsetY);
[self.view layoutIfNeeded];
CGFloat duration = 0.3;
if (hide)
{
[UIView animateWithDuration:duration animations:^{
self.quickLinkToolBarBotom.constant = -44.0;
} completion:nil];
}
else
{
[UIView animateWithDuration:duration animations:^{
self.quickLinkToolBarBotom.constant = 0.0;
} completion:nil];
}
[[self navigationController] setNavigationBarHidden:hide animated:YES];
}
So basically I have two methods that I run when the user clicks an Annotation in the map.
- (void) methodA{
[UIView animateWithDuration:kRequestButtonAnimationDuration animations:^(void){
self.button.transform = CGAffineTransformMakeTranslation(0,-(self.navigationController.view.frame.size.height - self.button.frame.origin.y)); }]; }
- (void) methodB:(double)value andBoolean:(BOOL) boolean{
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
if (boolean) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:value target:self selector:#selector(pullButtonUp) userInfo:nil repeats:NO];
} else{
self.timer = [NSTimer scheduledTimerWithTimeInterval:value target:self selector:#selector(showTabBar) userInfo:nil repeats:NO];
}}
-(void)pullButtonUp{
[(LLTabBarViewController*)self.tabBarController showTabBarAnimated];}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
[self methodA];
[self methodB:2.0 andBoolean:TRUE];
}
So during the first time I select an annotation, it works well: it runs methodA, then methodB after 2.0 seconds.
But when I try it again, it runs both A and B at the same time (basically methodA waits 2.0 seconds to execute).
Could this be related to Loops?
How should I track this problem? Any instrument? Which one?
I am a bit lost, help me please!
I think this is what you want to do
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
__weak typeof(self) weakSelf = self;
BOOL arbitraryBool = YES;
[UIView animateWithDuration:2
animations:^{
self.button.transform = CGAffineTransformMakeTranslation(0,-(self.navigationController.view.frame.size.height - self.button.frame.origin.y));
} completion:^(BOOL finished) {
if (finished) {
if (arbitraryBool) {
[weakSelf pullButtonUp];
} else {
[weakSelf showTabBar];
}
}
}]:
}
I want to zooming in out in WebView.I am newer in iOS.Please Help me.Some one say it is default property of WebView.I am testing in iOS8 . It does not work for me.
self.myWebView= [[UIWebView alloc] init];
[self.myWebView setScalesPageToFit:YES];
[self.myWebView setDelegate:self];
[self.myWebView.scrollView setDelegate:self];
[self.myWebView setDataDetectorTypes:UIDataDetectorTypeNone];
[self.myWebView.scrollView setBounces:NO];
[self.myWebView.scrollView setShowsHorizontalScrollIndicator:NO];
[self.myWebView.scrollView setShowsVerticalScrollIndicator:NO];
[myScrollView addSubview:self.myWebView];
- (void)webViewDidFinishLoad:(UIWebView *)theWebView
{
self.myWebView.scrollView.delegate = self;
self.myWebView.scrollView.maximumZoomScale = 20; // set as you want.
self.myWebView.scrollView.minimumZoomScale = 1; // set as you want.
}
(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
self.myWebView.scrollView.maximumZoomScale = 20;
}
if u are not use viewForZoomingInScrollView they work automatically. if you are use viewForZoomingInScrollView
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
if (scrollView ==myWebView.scrollView){
return self.myWebView;
}
else
{
return nil;
}
}
I try to create a UITexView with auto scrolling when press button start. And have a button stop, when pressed it will stop scrolling. Pressing button start again and it will continues to scroll down. How to handle this function.
I have research some code that this code below work with me.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(#"%f %f",_txvSentence.contentSize.width , _txvSentence.contentSize.height);
if (scrollingTimer == nil) {
scrollingTimer = [NSTimer scheduledTimerWithTimeInterval:(35.0/1000.0)
target:self
selector:#selector(autoscrollTimerFired:)
userInfo:nil
repeats:YES];
NSLog(#"%#",scrollingTimer);
}
}
- (void)autoscrollTimerFired:(NSTimer*)timer {
CGPoint scrollPoint = self.txvSentence.contentOffset;
//scrollPoint = CGPointMake(scrollPoint.x, scrollPoint.y + 1);
scrollPoint = _txvSentence.contentOffset;
scrollPoint.y= scrollPoint.y+1;
[_txvSentence setContentOffset:scrollPoint animated:NO];
//[self.txvSentence setContentOffset:scrollPoint animated:NO];
}
But i cannot stop this animation. And how to set dynamic duration such as when come to the end of text it automatically stop.
Sorry because my bad english. If not understand please tell me where I will explain it clearly.
Try this:
self.scrollView.scrollEnabled = NO;
CGFloat scrollHeight = 100;
//===
- (void) spinWithOptions: (UIViewAnimationOptions) options {
// this spin completes 360 degrees every 2 seconds
[UIView animateWithDuration:10
delay:0
options:options
animations:^{
self.scrollView.contentOffset = CGPointMake(0, scrollHeight);
}
completion:^(BOOL finished) {
if (finished) {
if (animating) {
// if flag still set, keep spinning with constant speed
[self spinWithOptions: UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction];
} else if (options != UIViewAnimationOptionCurveEaseOut) {
// one last spin, with deceleration
[self spinWithOptions: UIViewAnimationOptionCurveEaseOut];
}
}
}];
}
- (void) startAnimating {
if (!animating) {
animating = YES;
[self spinWithOptions: UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction];
}
}
- (void) stopAnimating {
// set the flag to stop spinning after one last 90 degree increment
animating = NO;
}
You can use NSTimer.
// Global var
CGFloat scrollHeight = MAX_HEIGHT;
CGFloat currentOffsetY = 0.0f;
NSTimer *timer;
self.timer = [NSTimer scheduledTimerWithTimeInterval:YOUR_TIME_INTERVAL target:self selector:#selector(scrollText:) userInfo:nil repeats:YES];
- (void)scrollText:(NSTimer *)timer {
currentOffsetY++;
if (currentOffsetY >= MAX_HEIGHT) {
[self.timer invalide];
}
self.scrollView.contentOffset = CGPointMake(0, currentOffsetY);
}
// Your button action
- (void)stopAnimation:(UIButton *)button {
[self.timer invalide];
}
I am trying to use dismissModalViewController:Animated: to dismiss my view, but it is not dismissing it, no matter what I try. You can see my attempts to release the view in the hideSplash method at the bottom. Please, if anyone can help it would be greatly appreciated. My code posted below:
#import "SplashViewController.h"
#implementation SplashViewController
- (void) didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void) viewDidUnload {
}
- (void) dealloc {
[super dealloc];
}
-(void) showSplash {
modalViewController = [[UIViewController alloc] init];
modalViewController.view = modelView;
[self presentModalViewController:modalViewController animated:NO];
[activityIndicator startAnimating ];
//[self bigcalculation];
//[self performSelector:#selector(hideSplash) withObject:nil afterDelay:2.0];
}
- (void) viewDidAppear:(BOOL)animated {
NSLog(#"View Did Appear");
[self bigcalculation];
}
- (void) bigcalculation {
NSLog(#"Big Calc Start");
for (int i = 0; i <= 648230; i++) {
for (int j = 0; j <= 1200; j++) {
}
}
NSLog(#"Big Calc End");
[self performSelector:#selector(hideSplash) withObject:nil];
}
- (void) hideSplash {
NSLog(#"Hide");
//[self dismissModalViewControllerAnimated:NO];
//[[self parentViewController] dismissModalViewControllerAnimated:YES];
[[self modalViewController] dismissModalViewControllerAnimated:YES];
NSLog(#"End Hide");
}
#end
The modal view controller is not responsible for dismissal. That burden is placed on the view controller that called the modalViewController.
Try replacing:
[[self modalviewController] dismissModalViewControllerAnimated:YES];
with
[self dismissModalViewControllerAnimated:YES];
Try to use this:
[self.parentViewController dismissModalViewControllerAnimated:NO];
I found the solution in case anyone else has this issue the line
[self performSelector:#selector(hideSplash) withObject:nil];
Should be
[self performSelector:#selector(hideSplash) withObject:nil afterDelay:0.0];