【问题标题】:Completing a location fetch within 'pull to refresh'?在“拉动刷新”中完成位置获取?
【发布时间】:2013-10-16 15:14:32
【问题描述】:

我已经在我的应用程序中实现了拉动刷新,当拉动时会启动位置管理器以修复用户位置,然后显示一个显示该位置的模态视图控制器。

我遇到的问题是,在获取用户位置之前显示模态视图控制器,导致空白地图持续几秒钟,直到它被获取和更新。

我有一个保存用户当前位置的属性。在拉动刷新调用“showMap”之前是否可以“保持”直到该属性不为零(即已建立位置),也许如果在设定的时间后无法找到用户,它只会显示错误?我尝试使用“while”循环来不断检查 currentLocation 属性,但这似乎不是正确的做法,而且无论如何也没有用。

这是我在 viewDidLoad 中设置的刷新代码:

__typeof (&*self) __weak weakSelf = self;

[self.scrollView addPullToRefreshWithActionHandler:^ {
    int64_t delayInSeconds = 1.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [weakSelf showMap];
    });
}];

当使用拉刷新时,它会调用这些方法:

- (void)showMap
{
    [self.locationManager updateCurrentLocation];

    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(finishRefresh) userInfo:nil repeats:NO];

}

- (void)finishRefresh
{
    [self.scrollView.pullToRefreshController didFinishRefresh];

    [self performSegueWithIdentifier:@"showMap" sender:self];
}

【问题讨论】:

    标签: objective-c cllocationmanager pull-to-refresh


    【解决方案1】:

    摘要

    为避免地图过早显示,您实际上应该等待异步更新操作,这样做最简洁的模式是委托。这是 a nice Apple Doc 在 Cocoa/Cocoa Touch 中的应用程序。

    那么它的工作原理大致是这样的:

    1. Pull-to-Refresh 触发位置更新。
    2. 位置更新完成后,locationManager 会通知您的控制器,控制器会显示地图。

    怎么做

    我不知道你的位置管理器类的接口,但如果是 CLLocationManager,它可以这样做。

    CLLocationManager 有一个委托属性。你的视图控制器应该:

    1. 符合CLLocationManagerDelegate protocol
    2. 将自己作为代表添加到locationManager
    3. 实现locationManager:didUpdateLocations: 方法——当位置数据到达并准备好使用时调用它。

    这个方法的实现大概是这样的:

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
    {
        /*
         *  shouldShowMap — BOOL property of View Controller, actually optional 
         *  but allowing to filter out handling of unwanted location updates 
         *  so they will not trigger map segue every time
         */
        if (self.shouldShowMap) {
            [self performSegueWithIdentifier:@"showMap" sender:self];
            self.shouldShowMap = NO; 
        }
        // stop updating location — you need only one update, not a stream of consecutive updates
        [self.locationManager stopUpdatingLocation];
    }
    

    您的 Pull-to-Refresh 处理程序应如下所示:

    __typeof (&*self) __weak weakSelf = self;
    
    [self.scrollView addPullToRefreshWithActionHandler:^ {
        self.shouldShowMap = YES;
        [weakSelf.locationManager startUpdatingLocation];
    }];
    

    希望它有所帮助。最好的学习方式(嗯,在大多数 情况下)是看看东西是如何在系统框架中实现的。朝那个方向思考,你肯定会想出一个解决方案:)

    如果您需要澄清,请随时询问,我可能解释得不够清楚。

    【讨论】:

    • 哇,伊万的回答很棒。我的位置管理器类是一个使用 CLLocationManager 的自定义类,并且对 didUpdateLocation: 的更新被传递到该类。我想我需要稍微重组它,以便将更新传递给我的控制器,以便它知道何时呈现地图。今天晚些时候我会听从你的建议。
    • 只是回来告诉您,这非常有效。感谢您帮助我指明正确的方向。
    • 很高兴它帮助了你!祝你的应用好运,编码愉快:)
    猜你喜欢
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多