Objective-C MapKit的使用-LBS简单的租车主界面demo
效果

分析
- 三个view:地图view、车辆信息view、车辆类型选择view
 
- 地图view:大头针的摆放,根据不同的种类显示大头针
 - 车辆信息view:根据当前点击的大头针显示对应的车辆信息
 - 车辆类型选择view:选择车辆类型
 
- 交互分析
 
- 选择车辆类型,地图上出现不同的大头针
 - 车辆信息view可滑动,滑动完成后地图定位到当前车辆的大头针上
 
- view的搭建
 
- 车辆选择view:自定义slider 分段滑竿(上一篇文章提到过)
 - 车辆信息View:使用uicollectionView的流水布局,做出分页效果
 - mapView:自定义大头针,根据类型选择不同的大头针图片
 
- 参数的传递
 
- 模拟数据通过编写1.plist完成
 - 读取plist数据,通过选择车辆类型,将筛选出来的数据使用模型数组存放,通过set方法传递给mapView和车辆信息view,并刷新界面
 - 选择车辆信息view 通过代理将当前显示的车辆信息页传递给mapview并定位
 - mapview有两个委托方法,
 点击空白处和点击大头针两个方法,用来设置车辆选择view和车辆信息view的显隐
代码
数据模型
- 数据模型及KVC使用
 
#import <Foundation/Foundation.h>
//车类型
typedef NS_ENUM(NSInteger, CarType) {
    CarTypeNone = -1,        //默认大头针
    CarTypeDaily,           //日租
    CarTypeHourly,          //时租
    CarTypeLong,            //长租
    CarTypeTestDrive,       //试驾
};
@interface CarModel : NSObject
@property(nonatomic,strong)NSDictionary *location;      //经纬度
@property(nonatomic,assign)NSString *carType;             //车类型
@property(nonatomic,copy)NSString *carName;             //车名称
@property(nonatomic,copy)NSString *price;               //价格
@property(nonatomic,copy)NSString *distance;            //与用户的距离
@property(nonatomic,copy)NSString *locationName;        //当前位置名
@property(nonatomic,copy)NSString *imageName;           //车图片
@property(nonatomic,copy)NSString *order;               //订单
@property(nonatomic,copy)NSString *banDay;              //限行
- (instancetype)initWithCarModelDict:(NSDictionary*)dict;
+ (instancetype)carModelWithDict:(NSDictionary*)ditc;
@end
自定义collectionview
使用xib的约束直接布局cell,cell外部公开carModel,用于赋值

- 给自定义的collectionview写一个委托,用来告诉controller当前选择cellitem
 
#import <UIKit/UIKit.h>
#import "CarModel.h"
@protocol CarInfoCollectionViewDelegate <NSObject>
- (void)selectItemArray:(NSArray*)array WithIndex:(NSInteger)index;
@end
@interface CarInfoCollectionView : UICollectionView
@property (nonatomic,strong)NSMutableArray<CarModel*> *carModelArray;
@property (nonatomic,strong)id<CarInfoCollectionViewDelegate> delegate2;
@end
- 界面呈现翻页效果 左右两边留上一页和下一页的边缘,需要计算停下的位置,使用
UICollectionViewDelegate代理方法 
//停下的位置
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
    UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout*)self.collectionViewLayout;
    //实际滑动的距离
    float pageWidth = layout.itemSize.width + layout.minimumLineSpacing;
    //当前位置
    float currentOffset = scrollView.contentOffset.x;
    //目标位置
    float targetOffset = targetContentOffset->x;
    float newTargetOffset = 0;
    int count = 0;
    if (targetOffset > currentOffset) {
        //向上取整
        count = ceilf(currentOffset / pageWidth);
        newTargetOffset = ceilf(currentOffset / pageWidth) * pageWidth;
    }else {
        //向下取整
        count = floorf(currentOffset / pageWidth);
        newTargetOffset = floorf(currentOffset / pageWidth) * pageWidth;
    }
    //处理边界
    if (newTargetOffset < 0)
        newTargetOffset = 0;
    else if (newTargetOffset > scrollView.contentSize.width)
        newTargetOffset = scrollView.contentSize.width;
    //设置目标位置指针
    targetContentOffset->x = currentOffset;
    //跳转新位置
    [scrollView setContentOffset:CGPointMake(newTargetOffset, 0) animated:YES];
}
- 当界面滚动完成时,通过代理通知controller当前的cellitem
 
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout*)self.collectionViewLayout;
    //实际滑动的距离
    int pageWidth = layout.itemSize.width + layout.minimumLineSpacing;
    //当前位置
    int currentOffset = scrollView.contentOffset.x;
    int count = currentOffset / pageWidth;
    NSLog(@"滚完了 %d",count );
    if ([self.delegate2 respondsToSelector:@selector(selectItemArray:WithIndex:)]) {
        [self.delegate2 selectItemArray:self.carModelArray WithIndex:count];
    }
}
mapView
- 代理
 
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "CarModel.h"
@protocol MapViewDelegate <NSObject>
//点击地图没有点到大头针
- (void)didSelectMapWithoutAnnotation;
//点到大头针
- (void)didSelectMapAnnotationViewWithCarArray:(NSMutableArray<CarModel *>*)carArray WithIndex:(NSInteger)index;
@end
@interface MapView : UIView
@property(nonatomic,strong)id<MapViewDelegate> delegate;
@property (nonatomic,strong)MKMapView *map;
//大头针数组
@property (nonatomic,strong)NSMutableArray *annotationArray;
//car数据模型数组
@property (nonatomic,strong)NSMutableArray<CarModel *> *carModelArray;
@end
- 使用到的全局变量
 
@interface MapView()<CLLocationManagerDelegate,MKMapViewDelegate>
@property (nonatomic,strong)CLLocationManager *locationManager;
@property (nonatomic,strong)UIButton *currentLocationBtn;
@property (nonatomic,strong)UIButton *zoomInBtn; //放大
@property (nonatomic,strong)UIButton *zoomOutBtn;//缩小
@property (nonatomic,strong)MyAnnotation *userLocationAnnotation;
@property (nonatomic,assign)int scale;
@end
- 初始化
 
//初始化
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.carModelArray = [NSMutableArray array];
        [self loadingMapInfo];
        [self addSubview:self.map];
        [self addSubview:self.currentLocationBtn];
        [self addSubview:self.zoomInBtn];
        [self addSubview:self.zoomOutBtn];
    }
    return self;
}
- 全局变量使用懒加载
需要提到的是当前位置的大头针的位置需要进行火星转码 
//当前位置大头针
- (MyAnnotation *)userLocationAnnotation {
    if (!_userLocationAnnotation) {
        _userLocationAnnotation = [[MyAnnotation alloc] init];
        _userLocationAnnotation.type = CarTypeNone;
        //转火星坐标
        CLLocationCoordinate2D currentLocation = [WGS84TOGCJ02 transformFromWGSToGCJ:self.locationManager.location.coordinate];
        _userLocationAnnotation.coordinate = currentLocation;
        _userLocationAnnotation.title = @"我的位置";
    }
    return _userLocationAnnotation;
}
- 定位当前位置和放大缩小按钮的实现
 
//定位
- (UIButton *)currentLocationBtn {
    if (!_currentLocationBtn) {
        _currentLocationBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.frame)*0.6, 50, 50)];
        [_currentLocationBtn setImage:[UIImage imageNamed:@"location_my.png"] forState:UIControlStateNormal];
        [_currentLocationBtn addTarget:self action:@selector(clickCurrentBtn) forControlEvents:UIControlEventTouchUpInside];
    }
    return _currentLocationBtn;
}
//点击定位
- (void)clickCurrentBtn {
    [self.map deselectAnnotation:self.userLocationAnnotation animated:NO];
    [self.map selectAnnotation:self.userLocationAnnotation animated:YES];
}
//放大
- (UIButton *)zoomInBtn {
    if (!_zoomInBtn) {
        _zoomInBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.frame)-60, CGRectGetHeight(self.frame)*0.55, 50, 50)];
        [_zoomInBtn setImage:[UIImage imageNamed:@"zoomin.png"] forState:UIControlStateNormal];
        [_zoomInBtn addTarget:self action:@selector(mapZoomIn) forControlEvents:UIControlEventTouchUpInside];
    }
    return _zoomInBtn;
}
//放大方法
- (void)mapZoomIn {
    MKCoordinateRegion region = self.map.region;
    region.span.latitudeDelta = region.span.latitudeDelta * 0.5;
    region.span.longitudeDelta = region.span.longitudeDelta * 0.5;
    [self.map setRegion:region animated:YES];
}
//缩小
- (UIButton *)zoomOutBtn {
    if (!_zoomOutBtn) {
        _zoomOutBtn = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.frame)-60, CGRectGetMaxY(self.zoomInBtn.frame), 50, 50)];
        [_zoomOutBtn setImage:[UIImage imageNamed:@"zoomout.png"] forState:UIControlStateNormal];
        [_zoomOutBtn addTarget:self action:@selector(mapZoomOut) forControlEvents:UIControlEventTouchUpInside];
    }
    return _zoomOutBtn;
}
//缩小方法
- (void)mapZoomOut {
    MKCoordinateRegion region = self.map.region;
    region.span.latitudeDelta = region.span.latitudeDelta * 2;
    region.span.longitudeDelta = region.span.longitudeDelta * 2;
    [self.map setRegion:region animated:YES];
}
- 授权使用定位功能 info.plist上添加
Privacy - Location Always Usage Description值随便填 
//获取授权
- (void)getAuthorization {
    //获取授权状态
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (status == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestAlwaysAuthorization];
    } else if (status == kCLAuthorizationStatusAuthorizedAlways) {
        //不跟随用户
        self.map.userTrackingMode = MKUserTrackingModeNone;
    }
}
//授权后进入
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
    //授权后开始定位
    [self.locationManager startUpdatingLocation];
    //加载地图信息
    [self loadData];
    [self loadingMapInfo];
}
- 公开变量设置set方法用于刷新地图大头针信息
 
//set方法
- (void)setCarModelArray:(NSMutableArray<CarModel *> *)carModelArray {
    for (MyAnnotation *an in self.map.annotations) {
        if (an.type != CarTypeNone) {
            [self.map removeAnnotation:an];
        }
    }
    [_carModelArray removeAllObjects];
    _carModelArray = carModelArray;
    //重新加载数据
    [self loadData];
}
//加载模拟数据
- (void)loadData {
    [self.annotationArray removeAllObjects];
    //完善model数据
    for (CarModel *model in self.carModelArray) {
        CLGeocoder *coder = [[CLGeocoder alloc] init];
        //model中的位置
        CLLocation *location = [[CLLocation alloc] initWithLatitude:[model.location[@"lat"] doubleValue] longitude:[model.location[@"long"] doubleValue]];
        //反地理编码 获得 经纬度 对应的 地名 并计算与当前位置的距离
        [coder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            CLPlacemark *mark = [placemarks firstObject];
            CLLocationCoordinate2D locatio = [WGS84TOGCJ02 transformFromWGSToGCJ:self.locationManager.location.coordinate];
            CLLocation *currentLocation =  [[CLLocation alloc] initWithLatitude:locatio.latitude longitude:locatio.longitude];
            CLLocationDistance dis = [location distanceFromLocation:currentLocation];
            model.locationName = mark.name;
            model.distance = [NSString stringWithFormat:@"%.2fkm",dis/1000];
        }];
    }
    int count = 0;
    //加载大头针
    for (CarModel *model in self.carModelArray) {
        MyAnnotation *annotation = [[MyAnnotation alloc] init];
        CLLocationCoordinate2D location = CLLocationCoordinate2DMake([model.location[@"lat"] doubleValue], [model.location[@"long"] doubleValue]);
        annotation.coordinate = location;
        annotation.index = count;
        annotation.type = [model.carType intValue];
        [self.map addAnnotation:annotation];
        [self.annotationArray addObject:annotation];
        count++;
    }
}
- mapview自身的代理方法,点击和取消大头针,实现回调跳转车辆信息view
 
#pragma mark - MKMapViewDelegate
//点击大头针
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    //重置汽车原来的颜色
    NSArray *array = [mapView annotations];
    for (MyAnnotation *an in array) {
        MKAnnotationView *v = [mapView viewForAnnotation:an];
        if ([v.reuseIdentifier isEqualToString:@"carViewID"]) {
            v.image = [self getCarImageWithTypeInAnnotation:an];
        }
    }
    //点击小车换颜色
    if ([view.reuseIdentifier isEqualToString:@"carViewID"]) {
        view.image = [UIImage imageNamed:@"pickcar.png"];
        //代理回调 通知界面 将 carInfoView 出现 carPickView消失
        if ([self.delegate respondsToSelector:@selector(didSelectMapAnnotationViewWithCarArray:WithIndex:)]) {
            [self.delegate didSelectMapAnnotationViewWithCarArray:self.carModelArray WithIndex:((MyAnnotation*)view.annotation).index];
        }
        //设置中心点和范围
        [self.map setRegion:MKCoordinateRegionMakeWithDistance(((MyAnnotation*)view.annotation).coordinate, 2000, 2000) animated:NO];
    }
    else {
        [self.map setRegion:MKCoordinateRegionMakeWithDistance(self.userLocationAnnotation.coordinate, 2000, 2000) animated:YES];
    }
}
//没有选中大头针
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
    //重置汽车原来的颜色
    NSArray *array = [mapView annotations];
    for (MyAnnotation *an in array) {
        MKAnnotationView *v = [mapView viewForAnnotation:an];
        if ([v.reuseIdentifier isEqualToString:@"carViewID"]) {
            v.image = [self getCarImageWithTypeInAnnotation:an];
        }
    }
    if ([view.reuseIdentifier isEqualToString:@"carViewID"]) {
        //代理回调 通知界面 将 carInfoView 消失 carPickView出现 小车变为未选中
        if ([self.delegate respondsToSelector:@selector(didSelectMapWithoutAnnotation)]) {
            [self.delegate didSelectMapWithoutAnnotation];
        }
    }
}
- 自定义大头针 当前位置使用标注 其他位置使用自定义的大头针视图
 
//当前位置大头针
- (MKPinAnnotationView*)customLocalAnnotationView:(id<MKAnnotation>)annotation {
    static NSString *locationID = @"locationViewID";
    //从缓存池中获取大头针
    MKPinAnnotationView *pinView = ( MKPinAnnotationView *)[self.map dequeueReusableAnnotationViewWithIdentifier:locationID];
    if (pinView == nil) {
        pinView  = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:locationID];
    }
    pinView.annotation = annotation;
    // 取消气泡显示
    pinView.canShowCallout = YES;
    // 设置大头针是否有下落动画
    pinView.animatesDrop = YES;
    return pinView;
}
//自定义大头针
- (MKAnnotationView*)customMKAnnotationView:(id<MKAnnotation>)annotation {
    //自定义大头针
    static NSString *carViewID = @"carViewID";
    //从缓存池中获取自定义大头针
    MKAnnotationView *annoView = [self.map dequeueReusableAnnotationViewWithIdentifier:carViewID];
    if (annoView == nil) {
        //缓存池中没有则创建
        annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:carViewID];
    }
    annoView.annotation = annotation;
    annoView.canShowCallout = NO;
    annoView.draggable = YES;
    annoView.image = [self getCarImageWithTypeInAnnotation:annotation];
    return annoView;
}
//根据大头针的类型返回图片
- (UIImage *)getCarImageWithTypeInAnnotation:(MyAnnotation*)annotation {
    switch (annotation.type) {
        case CarTypeDaily:
            return  [UIImage imageNamed:@"dailycar.png"];
            break;
        case CarTypeHourly:
            return [UIImage imageNamed:@"hourlycar.png"];
            break;
        case CarTypeLong:
            return [UIImage imageNamed:@"longcar.png"];
            break;
        case CarTypeTestDrive:
            return [UIImage imageNamed:@"testcar.png"];
            break;
        default:
            break;
    }
    return nil;
}
viewController主界面
- 将三个视图定义为全局 并使用懒加载
collectionView使用流水布局,为显示翻页效果需要配合增加头尾空白 
- (CarInfoCollectionView *)collectionView {
    if (!_collectionView) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        layout.itemSize = CGSizeMake(kScreenWidth * 0.85, kScreenHeight*0.2);
        layout.minimumLineSpacing = kScreenWidth * 0.05;
        CGFloat referenceWidth = (kScreenWidth - layout.itemSize.width - 2*layout.minimumLineSpacing)/2 + layout.minimumLineSpacing;
        layout.headerReferenceSize = CGSizeMake(referenceWidth, 0);
        layout.footerReferenceSize = CGSizeMake(referenceWidth, 0);
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        _collectionView = [[CarInfoCollectionView alloc] initWithFrame:CGRectMake(0, kScreenHeight*0.8, self.view.frame.size.width, kScreenHeight*0.2) collectionViewLayout:layout];
        _collectionView.hidden = YES;
        _collectionView.delegate2 = self;
    }
    return _collectionView;
}
- (MapView *)mapView {
    if (!_mapView) {
        _mapView = [[MapView alloc] initWithFrame:self.view.bounds];
        _mapView.delegate = self;
    }
    return _mapView;
}
- (CustomSlider *)carPickView {
    if (!_carPickView) {
        _carPickView = [[CustomSlider alloc] initWithFrame:CGRectMake(0, kScreenHeight*0.8, kScreenWidth, kScreenHeight*0.2)];
        _carPickView.backgroundColor = [UIColor whiteColor];
        _carPickView.sliderBarHeight = 10;
        _carPickView.numberOfPart = 4;
        _carPickView.partColor = [UIColor grayColor];
        _carPickView.sliderColor = [UIColor grayColor];
        _carPickView.thumbImage = [UIImage imageNamed:@"yuanxing.png"];
        _carPickView.partNameOffset = CGPointMake(0, -30);
        _carPickView.thumbSize = CGSizeMake(50, 50);
        _carPickView.partSize = CGSizeMake(20, 20);
        _carPickView.partNameArray = @[@"日租",@"时租",@"长租",@"试驾"];
        [_carPickView addTarget:self action:@selector(valuechange:) forControlEvents:UIControlEventValueChanged];
    }
    return  _carPickView;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.mapView];
    [self.view addSubview:self.collectionView];
    [self.view addSubview:self.carPickView];
    [self valuechange:self.carPickView];
}
- 从plist中加载数据
 
- (NSMutableArray<CarModel*> *) selectCarWithType:(CarType)type {
    NSMutableArray *resultArray = [NSMutableArray array];
    //读取数据
    NSString *path = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"plist"];
    NSArray *array = [NSArray arrayWithContentsOfFile:path];
    //存数据
    for (NSDictionary *dict in array) {
        CarModel *model = [CarModel carModelWithDict:dict];
        if ([model.carType intValue] == type) {
            [resultArray addObject:model];
        }
    }
    return resultArray;
}
- 实现各种委托方法
 
- (void)valuechange:(CustomSlider*)sender {
    NSLog(@"%ld",(long)sender.value);
    self.mapView.carModelArray = [self selectCarWithType:sender.value];
    NSLog(@"%@",self.mapView.carModelArray);
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
//collectionview 滚动结束后 调用
- (void)selectItemArray:(NSArray *)array WithIndex:(NSInteger)index {
    MyAnnotation *an = self.mapView.annotationArray[index];
    [self.mapView.map selectAnnotation:an animated:YES];
}
#pragma mark - mapViewDelegate
//点击地图没有点到大头针
- (void)didSelectMapWithoutAnnotation {
    self.carPickView.hidden = NO;
    self.collectionView.hidden = YES;
}
//点到大头针
- (void)didSelectMapAnnotationViewWithCarArray:(NSMutableArray<CarModel *> *)carArray WithIndex:(NSInteger)index {
    self.collectionView.carModelArray = carArray;
    NSLog(@"cararraycoutn =  %lu",(unsigned long)carArray.count);
    //跳转到选择的车辆信息
    [self.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
    //出现车辆信息动画
    self.carPickView.hidden = YES;
    self.collectionView.hidden = NO;
}
demo地址
https://github.com/gongxiaokai/EasyCarDemo
Objective-C MapKit的使用-LBS简单的租车主界面demo的更多相关文章
- win32最简单的htmlayout图形界面demo
		
1,下载HTMLayoutSDK,放在workspace. SDK下载地址:http://www.terrainformatica.com/htmlayout/HTMLayoutSDK.zip 2,v ...
 - socket.io简单说明及在线抽奖demo
		
socket.io简单说明及在线抽奖demo socket.io 简介 Socket.IO可以实现实时双向的基于事件的通信. 它适用于各种平台,浏览器或设备,也同样注重可靠性和速度. socket.i ...
 - 小程序实践(十):textarea实现简单的编辑文本界面
		
textarea是官方的原生组件,用于多行输入 简单的例子,监听文本内容.长度,以及设置最大可输入文本长度 wxml <view class='textarea-Style'> <t ...
 - 使用Bootstrap+metisMenu完成简单的后台管理界面
		
零. 写在前面 作者最近在一个小项目中需要写后台管理界面,在互联网上绕了一圈,最后决定使用Bootstrap+metisMenu来完成.理由1:Bootstrap是目前流行的前端框架,风格简约,简单易 ...
 - 如何使用AEditor制作一个简单的H5交互页demo
		
转载自:http://www.alloyteam.com/2015/06/h5-jiao-hu-ye-bian-ji-qi-aeditor-jie-shao/ 本教程演示如何使用AEditor制作一个 ...
 - 一个简单的MariaDB认证插件demo
		
代码地址如下:http://www.demodashi.com/demo/13076.html 一.前言 众所周知(其实可能很多人不知道)MariaDB支持插件认证.在MariaDB中新建用户,常见的 ...
 - Python 实现简单的登录注册界面
		
Python 实现简单的登录注册界面 注意:编写代码之前需要导入很重要的包 import tkinter as tk import pickle from tkinter import message ...
 - 巧用 mask-image 实现简单进度加载界面
		
最近给 nzoo 折腾官网,拿 angular2.0 + webpack 实现SPA,然后觉得最终打包后的出口文件有点大,用户首次访问会有一个时间较长的白屏等候界面,感觉体验不太好. 于是希望在用户下 ...
 - 一个简单的物料防错DEMO
		
前言 快2个月没写过博客了,就算是记流水账似的文章都没时间写,主要是太忙了:太多的bug要修复.太多由于bug引起的异常问题要解决.还有新的项目要开发,不忙怎么行呢?最近利用业余时间在鼓捣一个PDA的 ...
 
随机推荐
- 安装ecshop的问题处理
			
在安装Ecshop的时候,会遇到几个问题: 1.Strict Standards: Non-static method cls_image::gd_version() should not be ca ...
 - 聊聊vue组件开发的“边界把握”和“状态驱动”
			
vue有着完整的组件化开发机制,但是官网只给了开发的方式,对于开发规范以及组件化开发的最佳实践,还需要我们来摸索.本文就平时开发中的经验来谈谈“把握边界”和“状态驱动”这两个话题. 边界把握 边界把握 ...
 - [1] MVC & MVP &MVVM
			
开发架构之MVC & MVP & MVVM
 - 常用DOM API
			
Node Node是一个接口,中文叫节点,很多类型的DOM元素都是继承于它,都共享着相同的基本属性和方法.常见的Node有 element,text,attribute,comment,documen ...
 - Microsoft Excel 自动取数据库数据
			
1.下载安装mysql-connector-odbc-5.1.5-win32.msi 2.打开控制面板.搜索数据 3.点击添加→MySQL ODBC 5.1 Driver→完成 4.填写名称.IP地址 ...
 - XCOM2中敌对生物设计分析(Aliens篇)
			
Aliens Aliens作为游戏设定中入侵的外星人,有各式外貌及奇特的战斗方式,掌握一些高能科技或利用精神力量进行攻击 Sectoid 使用灵能战斗的外星人,并无高级版本,初级便会使用精神控制,生命 ...
 - 远程调用其它站点并设置cookie
			
远程调用其它站点并设置cookie: 参考js var domainArray = [ {site:'g.com',action:'/b.do?c' } ,{site:'www.baidu.com', ...
 - 关于ZendStudio 10.5的破解 包括mac
			
一. 下载ZendStudio 10.5 首先下载ZendStudio 10.5 我使用的是mac版 下载地址是: http://downloads.zend.com/studio-eclipse/1 ...
 - DataFrame创建
			
DataFrame/DataSet 创建 读文件接口 import org.apache.spark.sql.SparkSession val spark = SparkSession .builde ...
 - Example004自动关闭的广告窗口
			
<!-- 实例004自动关闭的广告窗口--> <!-- 3秒后关闭 --> <body onload="window.setTimeout('window.cl ...