UIScrollView 带有图像幻灯片和计时器

发布于 2024-11-09 04:45:18 字数 2851 浏览 0 评论 0原文

我正在尝试实现带有水平和垂直预览的图像幻灯片,并且我希望能够在用户停止滚动时执行一些操作,并在 5 秒后执行此操作。我使用 2 个计时器来处理这个问题,但我需要一些同步,或者也许我的方式是错误的!为什么我使用 2 个计时器:因为我想处理主视图中的滚动(-(void)touchesBegan-(void)touchesEnded)并在滚动视图上滚动( <代码>UIScrollView委托)。我的代码如下,希望有人可以提供帮助:)。谢谢。

// This is the slideShow view controller
// It display all the images with preview (right, left, up and down)
@interface ImageSlideShowViewController : UIViewController<UIScrollViewDelegate>
{

    UIScrollView *scrollViewForSlideShow;    
    // Timers
    NSTimer *autoscrollTimer;
    NSTimer *mainViewTimer;
}

@end

@implementation ImageSlideShowViewController

#pragma mark Touch handling

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    ....
    // Invalidate all timers
   [autoscrollTimer invalidate];
   autoscrollTimer = nil;
   [mainViewTimer invalidate];
   mainViewTimer = nil;
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    ....

    assert(mainViewTimer == nil);

    mainViewTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                       target:self
                                                     selector:@selector(allViewTimerFireMethod:)
                                                     userInfo:nil
                                                      repeats:NO];   


    // prev image horizontal
        ...

    // next image horizontal
        ....    

    // prev image vertical
            ...

    // next image vertical
            ....
}   


#pragma mark -
#pragma mark UIScrollView delegate

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // Invalidate all timers
    [autoscrollTimer invalidate];
    autoscrollTimer = nil;
    [mainViewTimer invalidate];
    mainViewTimer = nil;
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 
{
    //Doing some management stuff here
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (!scrollView.dragging)
    {
        //Doing some management stuff here

        assert(autoscrollTimer == nil);


        autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                           target:self
                                                         selector:@selector(timerFireMethod:)
                                                         userInfo:nil
                                                          repeats:NO];

    }
}

#pragma mark -
#pragma mark Timers methods

- (void)timerFireMethod:(NSTimer*)theTimer
{
    autoscrollTimer = nil;
    // Call a method that dispaly the image
}

- (void)allViewTimerFireMethod:(NSTimer *)theTimer
{
    mainViewTimer = nil;
    // Call a method that dispaly the image (same as the method called above)
}

@end

i'm trying to implement a slideshow of images with previews horizontaly and vertically, and i want to be able to do some stuff when the user stop scrolling and after 5 seconds do this stuff. I use 2 timers to handle this but i need some synchronization or maybe i'm in the wrong way! Why i use 2 timers : because i want to handle scrolling in the main view (-(void)touchesBegan and -(void)touchesEnded)and scrolling on the scrollView( UIScrollView delegate). my code is below and i hope someone can help :). Thanks.

// This is the slideShow view controller
// It display all the images with preview (right, left, up and down)
@interface ImageSlideShowViewController : UIViewController<UIScrollViewDelegate>
{

    UIScrollView *scrollViewForSlideShow;    
    // Timers
    NSTimer *autoscrollTimer;
    NSTimer *mainViewTimer;
}

@end

@implementation ImageSlideShowViewController

#pragma mark Touch handling

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    ....
    // Invalidate all timers
   [autoscrollTimer invalidate];
   autoscrollTimer = nil;
   [mainViewTimer invalidate];
   mainViewTimer = nil;
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    ....

    assert(mainViewTimer == nil);

    mainViewTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                       target:self
                                                     selector:@selector(allViewTimerFireMethod:)
                                                     userInfo:nil
                                                      repeats:NO];   


    // prev image horizontal
        ...

    // next image horizontal
        ....    

    // prev image vertical
            ...

    // next image vertical
            ....
}   


#pragma mark -
#pragma mark UIScrollView delegate

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // Invalidate all timers
    [autoscrollTimer invalidate];
    autoscrollTimer = nil;
    [mainViewTimer invalidate];
    mainViewTimer = nil;
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 
{
    //Doing some management stuff here
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (!scrollView.dragging)
    {
        //Doing some management stuff here

        assert(autoscrollTimer == nil);


        autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                           target:self
                                                         selector:@selector(timerFireMethod:)
                                                         userInfo:nil
                                                          repeats:NO];

    }
}

#pragma mark -
#pragma mark Timers methods

- (void)timerFireMethod:(NSTimer*)theTimer
{
    autoscrollTimer = nil;
    // Call a method that dispaly the image
}

- (void)allViewTimerFireMethod:(NSTimer *)theTimer
{
    mainViewTimer = nil;
    // Call a method that dispaly the image (same as the method called above)
}

@end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

揪着可爱 2024-11-16 04:45:18

我认为您可以摆脱这两个计时器并定义一个中间函数,例如 enableTimerFor:,您可以从 -scrollViewDidEndDecelerating:-touchesEnded 调用它: withEvent: 而不是在那里创建 2 个计时器。

enableTimerFor: 基本上会创建计时器并安排它:

-(void)enableTimerFor:(NSUInteger)callerId {
    viewTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                   target:self
                                                 selector:@selector(timerFired:)
                                                 userInfo:nil
                                                  repeats:NO];   
}

-(void)timerFired {
   // do whatever you need to
}

它将像这样调用:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    ....
    [self enableTimerFor:kTouchesEnded];
    ....
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if (!scrollView.dragging) {
        //Doing some management stuff here
        [self enableTimerFor:kScrollEnded];
    }
    ....
}

这样,同步就没有问题了。另请注意,我认为 enableTimerFor: 有一个参数,可让您识别它是从一个函数还是另一个函数调用,但您可以轻松决定删除它,以防万一您不这样做不需要区分这两种情况。

我不确定这个建议是否适合您,因为我不知道您的解决方案的所有细节,但我仍然认为这是鉴于我所掌握的信息的最直接的建议。

I think that you could get rid of the two timers and define an intermediate function, say enableTimerFor:, that you could call from -scrollViewDidEndDecelerating: and -touchesEnded:withEvent: instead of creating there the 2 timers.

enableTimerFor: would basically create the timer and schedule it:

-(void)enableTimerFor:(NSUInteger)callerId {
    viewTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
                                                   target:self
                                                 selector:@selector(timerFired:)
                                                 userInfo:nil
                                                  repeats:NO];   
}

-(void)timerFired {
   // do whatever you need to
}

And it would be called like this:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    ....
    [self enableTimerFor:kTouchesEnded];
    ....
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if (!scrollView.dragging) {
        //Doing some management stuff here
        [self enableTimerFor:kScrollEnded];
    }
    ....
}

Like that, you would have no problem in syncing. Notice also that I thought of enableTimerFor: as having a parameter that allows you to identify whether it was called from one function or the other, but you can decide easily to get rid of it in case you don't need to distinguish the two cases.

I am not sure that this suggestion could work well for you, since I don't know all the details of your solution, but still I think this is the most direct suggestion given the information I have.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文