zoukankan      html  css  js  c++  java
  • 【iOS】7.4 定位服务->2.1.3.3 定位

    本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正。


    本文相关目录:
    ================== 所属文集:【iOS】07 设备工具 ==================
    7.4 定位服务->1.0 简介
    7.4 定位服务->2.1.1 定位 - 官方框架CoreLocation: 请求用户授权
    7.4 定位服务->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager位置管理器
    7.4 定位服务->2.1.3.1 定位 - 官方框架CoreLocation 功能1:地理定位
    7.4 定位服务->2.1.3.2 定位 - 官方框架CoreLocation 功能2:地理编码和反地理编码
    7.4 定位服务->2.1.3.3 定位 - 官方框架CoreLocation 功能3:区域监听
    7.4 定位服务->2.1.4 定位 - 官方框架CoreLocation 案例:指南针效果
    7.4 定位服务->2.2 定位 - locationManager框架
    7.4 定位服务->3.1 地图框架MapKit 功能1:地图展示
    7.4 定位服务->3.2 地图框架MapKit 功能2:路线规划(导航)
    7.4 定位服务->3.3 地图框架MapKit 功能3:3D视图
    7.4 定位服务->3.4 地图框架MapKit 功能4:地图截图
    7.4 定位服务->3.5 地图框架MapKit 功能5:POI检索
    ================== 所属文集:【iOS】07 设备工具 ==================


    定位目录:

    官方框架CoreLocation目录:

    定位的功能实现:

    本文目录:


    1.0 概念解释


    2.0 监听思路


    3.0 问题:区域监听, 测试没有效果?


    代码7:区域监听 Demo

    编译环境:Xcode 8.0
    模拟器版本:iOS 10
    Swift版本:3.0

    【OC 语言】
    
    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface ViewController () <CLLocationManagerDelegate>
    @property(nonatomic, strong) CLLocationManager *locationM;
    @end
    
    @implementation ViewController
    
    #pragma mark - 懒加载
    - (CLLocationManager *)locationM {
        if (!_locationM) {
            // 创建CLLocationManager对象并设置代理
            _locationM = [[CLLocationManager alloc] init];
            _locationM.delegate = self;
            
            // 请求前后台定位, 或前台定位授权, 并在Info.Plist文件中配置相应的Key
            if ([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)]) {
                [_locationM requestAlwaysAuthorization];
            }
        }
        return _locationM;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        if([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]])
        {
        
        // 0.判断区域监听服务是否可用(定位服务是否关闭, 定位是否授权,是否开启飞行模式)
            if ([CLLocationManager isMonitoringAvailableForClass:[CLCircularRegion class]]) {
          
            // 1.创建区域中心
            CLLocationCoordinate2D center = CLLocationCoordinate2DMake(21.123, 124.345);
            // 指定区域半径
            CLLocationDistance radius = 100;
            
            // 区域半径如果大于最大区域监听半径,则无法监听成功
            if (radius > self.locationM.maximumRegionMonitoringDistance) {
                radius = self.locationM.maximumRegionMonitoringDistance;
            }
            
            // 根据区域中心和区域半径创建一个区域
            CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center
                                                                         radius:radius
                                                                     identifier:@"TD"];
            
            // 2. 开始监听指定区域 (这个方法, 只会当进入或者离开区域这个动作触发时, 才会调用对应的代理方法)
            [self.locationM startMonitoringForRegion:region];
            
            // 请求获取某个区域的当前状态
            [self.locationM requestStateForRegion:region];
        } else {
            NSLog(@"区域监听不可用");
        }
     }
    }
    
    #pragma mark - CLLocationManagerDelegate
    #pragma mark - 进入监听区域后调用(调用一次)
    - (void)locationManager:(nonnull CLLocationManager *)manager didEnterRegion:(nonnull CLRegion *)region {
        
        NSLog(@"进入区域---%@", region.identifier);
    }
    
    #pragma mark - 进入监听区域后调用(调用一次)
    - (void)locationManager:(nonnull CLLocationManager *)manager didExitRegion:(nonnull CLRegion *)region {
        
        NSLog(@"离开区域---%@", region.identifier);
    }
    
    #pragma mark - 当监听区域失败时调用
    // 监听区域个数是有上限的,如果大于上限,再注册区域就会失败,就会执行此方法)
    - (void)locationManager:(nonnull CLLocationManager *)manager
    monitoringDidFailForRegion:(nullable CLRegion *)region
                  withError:(nonnull NSError *)error {
        
        // 经验: 一般都是在此处把比较远的区域给移除
    //    [manager stopMonitoringForRegion:region];
    }
    
    #pragma mark - 请求某个区域状态时, 回调的代理方法
    - (void)locationManager:(CLLocationManager *)manager
          didDetermineState:(CLRegionState)state
                  forRegion:(CLRegion *)region {
        
        switch (state) {
            case CLRegionStateUnknown:
                NSLog(@"未知状态");
                break;
            case CLRegionStateInside:
                NSLog(@"在区域内部");
                break;
            case CLRegionStateOutside:
                NSLog(@"在区域外部");
                break;
            default:
                break;
        }
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    打印结果:

    OC - 区域监听[12621:389819] 在区域内部
    
    OC - 区域监听[12621:389819] 离开区域---TD
    OC - 区域监听[12621:389819] 在区域外部
    
    OC - 区域监听[12621:389819] 进入区域---TD
    OC - 区域监听[12621:389819] 在区域内部
    

    【Swift语言】

    
    import UIKit
    import CoreLocation
    
    class ViewController: UIViewController {
        
        @IBOutlet weak var Label: UILabel!
        
        lazy var locationM: CLLocationManager = {
            
            let locationM = CLLocationManager()
            locationM.delegate = self
            
            // 请求授权 配置key
            if #available(iOS 8.0, *) {
                locationM.requestAlwaysAuthorization()
            }
            return locationM
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // 如果想要进行区域监听, 在ios8.0之后, 必须要请求用户的位置授权
            
            // 0. 先判断区域监听是否可用
            if CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self){
            
            // 1. 创建区域中心
            let center = CLLocationCoordinate2DMake(21.123, 124.345)
            var distance: CLLocationDistance = 10
            
            // 区域半径如果大于最大区域监听半径,则无法监听成功
            if distance > locationM.maximumRegionMonitoringDistance {
                distance = locationM.maximumRegionMonitoringDistance
            }
            
            // 根据区域中心和区域半径创建一个区域
            let region  = CLCircularRegion(center: center, radius: distance, identifier: "TD")
            
            // 2. 开始监听指定区域 (这个方法, 只会当进入或者离开区域这个动作触发时, 才会调用对应的代理方法)
            locationM.startMonitoring(for: region)
            
            // 请求获取某个区域的当前状态
            locationM.requestState(for: region)
            
            }else{
                print("区域监听不可用")
            }
        }
        
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    
    extension ViewController: CLLocationManagerDelegate {
        
        // 进入区域时调用
        func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
            print("进入区域--" + region.identifier)
            Label.text = "进入区域"
        }
        
        // 离开区域时调用
        func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
            print("离开区域--" + region.identifier)
            Label.text = "离开区域"
        }
        
        // 当请求某个区域状态时, 如果获取到对应状态就会调用这个方法
        func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
            
            if region.identifier == "TD" {
                if state == CLRegionState.inside{
                    Label.text = "您已进入---" + region.identifier + "区域"
                }else if state == CLRegionState.outside {
                    Label.text = "您已离开---" + region.identifier + " 区域"
                }else {
                    Label.text = "其他"
                }
            }
        }    
    }
    

    打印结果:

    进入区域--TD
    离开区域--TD
    


    本文源码 Demo 详见 Github
    https://github.com/shorfng/iOS_7.0_Device-Tools


    作者:蓝田(Loto)
    【作品发布平台】

    简书
    博客园
    Gitbook(如果觉得文章太长,请阅读此平台发布的文章)

    【代码托管平台】

    Github

    【如有疑问,请通过以下方式交流】

    评论区回复
    发送邮件shorfng@126.com


    本文版权归作者和本网站共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,谢谢合作。


    如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
    • 支付宝扫一扫 向我打赏

    • 你也可以微信 向我打赏

  • 相关阅读:
    hadoop hdfs总结 NameNode部分 概述
    最近近况
    hadoop hdfs总结 NameNode部分 1
    rsync 使用
    SmartHost
    hadoop unit test 问题
    git 使用记录
    java 类内存分配计算
    hadoop hdfs总结 NameNode部分 2
    0417 430调试技巧
  • 原文地址:https://www.cnblogs.com/shorfng/p/6604650.html
Copyright © 2011-2022 走看看