iOS开发-实现地区选择三级联动

Map.png

前言:对于地区的选择使用的地方还是比较多的,而地区选择的使用一般都是伴随着联动,常用的二级和三级的联动效果比较多一些。今天小编给大家主要介绍一下地区选择三级联动的实现。相信大家会了三级的联动效果,那么二级联动就是信手拈来了。

原理:使用代理传值。地区选择的菜单栏和展示选择区分开定制,同时通过代理方法将值和事件传递并进行相应的view刷新。如果有兴趣的朋友还可以把这两个view合并到一个新的整体view中进行再次封装。

首先,大家先来看一下效果图

地区选择三级联动.gif

下面,我们先来创建地区选择的菜单栏的view.h如下:

#import <UIKit/UIKit.h>

@protocol PickPlaceMenuDelegate;
@interface PickPlaceMenu : UIView

@property (nonatomic, weak) id<PickPlaceMenuDelegate> delegate;

/**
 配置菜单

 @param province 省
 @param city     市
 @param district 区/县
 */
- (void)configViewWithProvince:(NSString *)province city:(NSString *)city district:(NSString *)district;

/**
 重置菜单
 */
- (void)reset;
@end
@protocol PickPlaceMenuDelegate <NSObject>

//代理方法
@optional
/**
 点击菜单

 @param menuView 菜单view
 @param index    选中菜单的下标:0代表省,1代表市,2代表区/县
 @param isShow   是否弹出显示当前的对应列表
 */
- (void)menuView:(PickPlaceMenu *)menuView didSelectAtIndex:(NSInteger)index isShow:(BOOL)isShow;
@end

所有方法和代理都给大家注释了,这里不再多说,接下来我们来看在.m中的布局及实现如下:

#import "PickPlaceMenu.h"

@interface PickPlaceMenu ()

@property (nonatomic, strong) UIButton * btn_province;
@property (nonatomic, strong) UIButton * btn_city;
@property (nonatomic, strong) UIButton * btn_district;
@property (nonatomic, strong) UILabel * lab_lineV1;
@property (nonatomic, strong) UILabel * lab_lineV2;
@property (nonatomic, strong) UILabel * lab_lineH;
@end

@implementation PickPlaceMenu

- (instancetype)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    if (self) {
        
        self.backgroundColor = [UIColor whiteColor];
        [self addSubviews];
    }
    return self;
}

#pragma mark - add subviews

- (void)addSubviews {
    
    [self addSubview:self.btn_province];
    [self addSubview:self.btn_city];
    [self addSubview:self.btn_district];
    [self addSubview:self.lab_lineV1];
    [self addSubview:self.lab_lineV2];
    [self addSubview:self.lab_lineH];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    float width = self.bounds.size.width;
    [_btn_province mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.mas_equalTo(@((width - 2)/3));
        make.top.mas_equalTo(@0);
        make.bottom.mas_equalTo(@-1);
        make.left.mas_equalTo(@0);
    }];
    
    [_lab_lineV1 mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.mas_equalTo(@1);
        make.top.mas_equalTo(@5);
        make.bottom.mas_equalTo(@-6);
        make.left.mas_equalTo(_btn_province.mas_right);
    }];
    
    [_btn_city mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.mas_equalTo(@((width - 2)/3));
        make.top.mas_equalTo(@0);
        make.bottom.mas_equalTo(@-1);
        make.left.mas_equalTo(_lab_lineV1.mas_right);
    }];
    
    [_lab_lineV2 mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.mas_equalTo(@1);
        make.top.mas_equalTo(@5);
        make.bottom.mas_equalTo(@-6);
        make.left.mas_equalTo(_btn_city.mas_right);
    }];
    
    [_btn_district mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.mas_equalTo(@((width - 2)/3));
        make.top.mas_equalTo(@0);
        make.bottom.mas_equalTo(@-1);
        make.left.mas_equalTo(_lab_lineV2.mas_right);
    }];
    
    [_lab_lineH mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.size.mas_equalTo(CGSizeMake(Screen_Width, 1));
        make.left.mas_equalTo(@0);
        make.bottom.mas_equalTo(@0);
    }];
}

#pragma mark - config view

- (void)configViewWithProvince:(NSString *)province city:(NSString *)city district:(NSString *)district {
    
    if (province) {
        
        [_btn_province setTitle:province forState:UIControlStateNormal];
    }
    
    if (city) {
        
        [_btn_city setTitle:city forState:UIControlStateNormal];
    }
    
    if (district) {
        
        [_btn_district setTitle:district forState:UIControlStateNormal];
    }
}

- (void)reset {
    
    if (_btn_province.selected) {
        
        _btn_province.selected = NO;
    }
    
    if (_btn_city.selected) {
        
        _btn_city.selected = NO;
    }
    
    if (_btn_district.selected) {
        
        _btn_district.selected = NO;
    }
}

#pragma mark - button event

- (void)clickSelectProvince:(UIButton *)sender {
    
    sender.selected = !sender.selected;
    _btn_city.selected = NO;
    _btn_district.selected = NO;
    
    if ([self.delegate respondsToSelector:@selector(menuView:didSelectAtIndex:isShow:)]) {
        
        [self.delegate menuView:self didSelectAtIndex:0 isShow:sender.selected];
    }
}

- (void)clickSelectCity:(UIButton *)sender {
    
    sender.selected = !sender.selected;
    _btn_province.selected = NO;
    _btn_district.selected = NO;
    
    if ([self.delegate respondsToSelector:@selector(menuView:didSelectAtIndex:isShow:)]) {
        
        [self.delegate menuView:self didSelectAtIndex:1 isShow:sender.selected];
    }
}

- (void)clickSelectDistrict:(UIButton *)sender {
    
    sender.selected = !sender.selected;
    _btn_province.selected = NO;
    _btn_city.selected = NO;
    
    if ([self.delegate respondsToSelector:@selector(menuView:didSelectAtIndex:isShow:)]) {
        
        [self.delegate menuView:self didSelectAtIndex:2 isShow:sender.selected];
    }
}

#pragma mark - setter and getter

- (UIButton *)btn_province {
    
    if (!_btn_province) {
        
        _btn_province = [[UIButton alloc] init];
        _btn_province.titleLabel.font = [UIFont systemFontOfSize:15];
        [_btn_province setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_btn_province setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected];
        [_btn_province addTarget:self action:@selector(clickSelectProvince:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _btn_province;
}

- (UIButton *)btn_city {
    
    if (!_btn_city) {
        
        _btn_city = [[UIButton alloc] init];
        _btn_city.titleLabel.font = [UIFont systemFontOfSize:15];
        [_btn_city setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_btn_city setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected];
        [_btn_city addTarget:self action:@selector(clickSelectCity:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _btn_city;
}

- (UIButton *)btn_district {
    
    if (!_btn_district) {
        
        _btn_district = [[UIButton alloc] init];
        _btn_district.titleLabel.font = [UIFont systemFontOfSize:15];
        [_btn_district setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_btn_district setTitleColor:[UIColor orangeColor] forState:UIControlStateSelected];
        [_btn_district addTarget:self action:@selector(clickSelectDistrict:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _btn_district;
}

- (UILabel *)lab_lineV1 {
    
    if (!_lab_lineV1) {
        
        _lab_lineV1 = [[UILabel alloc] init];
        _lab_lineV1.backgroundColor = Color_Line;
    }
    return _lab_lineV1;
}

- (UILabel *)lab_lineV2 {
    
    if (!_lab_lineV2) {
        
        _lab_lineV2 = [[UILabel alloc] init];
        _lab_lineV2.backgroundColor = Color_Line;
    }
    return _lab_lineV2;
}

- (UILabel *)lab_lineH {
    
    if (!_lab_lineH) {
        
        _lab_lineH = [[UILabel alloc] init];
        _lab_lineH.backgroundColor = Color_Line;
    }
    return _lab_lineH;
}
@end

大家可以看到,这里是用了三个按钮来实现的菜单点击效果,这个按钮和布局,大家可以根据自己的需求进行相应的修改,不过事件的处理和代理的赋值基本是不需要修改的。

接下来,我们继续创建展示地区选择列表的一个view.h如下:

#import <UIKit/UIKit.h>

@protocol PickPlaceViewDelegate;
@interface PickPlaceView : UIView

@property (nonatomic, weak) id<PickPlaceViewDelegate> delegate;

/**
 刷新展示地区的列表view

 @param dataArr   数据源:省/市/ 区、县
 @param component 菜单选中下标(这里我称之为列)
 */
- (void)reloadViewWithData:(NSArray *)dataArr component:(NSInteger)component;

/**
 收起列表
 */
- (void)hide;
@end
@protocol PickPlaceViewDelegate <NSObject>

// 代理方法
@optional

/**
 选中地区

 @param placeView 地区view
 @param place     选中的地区
 @param component 在菜单的第几个(列)
 @param row       选中的在第几行
 */
- (void)placeView:(PickPlaceView *)placeView didSelectPlace:(NSString *)place atComponent:(NSInteger)component atRow:(NSInteger)row;

/**
 展示地区view收起
 */
- (void)placeViewDidHide;

@end

这里也都添加了注释,相信大家都能够看的明白。我们继续来看在.m中的实现如下:

#import "PickPlaceView.h"

#define Cell_Place    @"Cell_Place"
@interface PickPlaceView () <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UITableView * tableView;

@property (nonatomic, strong) NSMutableArray * dataArr;
@property (nonatomic, assign) NSInteger index;

@property (nonatomic, assign) float kWidth;
@property (nonatomic, assign) float kHeight;
@end
@implementation PickPlaceView

- (instancetype)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    if (self) {
        
        [self addSubviews];
    }
    return self;
}

#pragma mark - add subviews

- (void)addSubviews {
    
    [self addSubview:self.tableView];
}

#pragma mark - layout subviews

- (void)layoutSubviews {
    [super layoutSubviews];
    
    _kWidth = self.bounds.size.width;
    _kHeight = self.bounds.size.height;
}

#pragma mark - public method

- (void)reloadViewWithData:(NSArray *)dataArr component:(NSInteger)component {
    
    _index = component;
    self.dataArr = [NSMutableArray arrayWithArray:dataArr];
    
    float height = self.dataArr.count * 44;
    if (_kHeight - height > 0) {
        
        _tableView.frame = CGRectMake(0, -height, _kWidth, height);
    } else {
        
        _tableView.frame = CGRectMake(0, -_kHeight, _kWidth, _kHeight);
    }
    [_tableView reloadData];
    
    [self show];
}

#pragma mark - touch event

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    if ([self.delegate respondsToSelector:@selector(placeViewDidHide)]) {
        
        [self.delegate placeViewDidHide];
    }
    [self hide];
}

#pragma mark - tableView dataSource and delegate

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    return self.dataArr.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:Cell_Place forIndexPath:indexPath];
    
    if (indexPath.row < self.dataArr.count) {
        
        cell.textLabel.font = [UIFont systemFontOfSize:15];
        cell.textLabel.text = _dataArr[indexPath.row];
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NSString * place = self.dataArr[indexPath.row];
    
    if ([self.delegate respondsToSelector:@selector(placeView:didSelectPlace:atComponent:atRow:)]) {
        
        [self.delegate placeView:self didSelectPlace:place atComponent:_index atRow:indexPath.row];
    }
    [self hide];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    float offset = scrollView.contentOffset.y;
    
    if (offset <= 0) {
        
        [scrollView setContentOffset:CGPointMake(0, 0)];
    }
}

#pragma mark - private method

- (void)show {
    
    [UIView animateWithDuration:0.25 animations:^{
        
        self.backgroundColor = Color_RGB_Alpha(0, 0, 0, 0.3);
        _tableView.frame = CGRectMake(0, 0, _kWidth, _tableView.bounds.size.height);
    }];
}

- (void)hide {
    
    [UIView animateWithDuration:0.15 animations:^{
        
        self.backgroundColor = Color_RGB_Alpha(0, 0, 0, 0);
        _tableView.frame = CGRectMake(0, -_kHeight, _kWidth, _kHeight);
    } completion:^(BOOL finished) {
        
        self.hidden = YES;
    }];
}

#pragma mark - setter and getter

- (UITableView *)tableView {
    
    if (!_tableView) {
        
        _tableView = [[UITableView alloc] init];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.backgroundColor = Color_RGB_Alpha(0, 0, 0, 0);
        [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:Cell_Place];
        _tableView.tableFooterView = [[UIView alloc] init];
    }
    return _tableView;
}

- (NSMutableArray *)dataArr {
    
    if (!_dataArr) {
        
        _dataArr = [[NSMutableArray alloc] init];
    }
    return _dataArr;
}
@end

这里使用了UITableView来进行列表的展示,并通过动画来实现向下弹出和向上收起的动画效果及半透明背景的渐变效果。每次调用外漏刷新数据方法时,列表刷新数据并向下弹出,选中或者点击空白地方时向上收起,同时回调该事件。以让菜单栏也进行相应的view的刷新。

封装基本完成,下面我们来简单看一下使用方法。
这里,我建了一个Header类才存储所有的头文件,使用时只需要导入该Header类就可以了。为了使数据看起来更整洁,我简单写了一个城市地区的plist文件,里边简单存了几个城市。

#import "ViewController.h"
#import "PickPlace.h"

@interface ViewController () <PickPlaceMenuDelegate, PickPlaceViewDelegate>

@property (nonatomic, strong) PickPlaceMenu * view_menu;
@property (nonatomic, strong) PickPlaceView * view_place;

@property (nonatomic, strong) NSMutableArray * placeArr;

@property (nonatomic, assign) NSInteger provinceIndex;
@property (nonatomic, assign) NSInteger cityIndex;
@property (nonatomic, assign) NSInteger districtIndex;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.navigationItem.title = @"地区选择";
    
    [self loadData];
    [self addSubviews];
    [self makeConstraintsForUI];
}

#pragma mark - load data

- (void)loadData {
    
    _provinceIndex = 0;
    _cityIndex = 0;
    _districtIndex = 0;
    
    NSDictionary * dic = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Place" ofType:@"plist"]];
    NSLog(@"%@", dic);
    NSArray * provinceArr = dic[@"province"];
    
    for (int i = 0; i < provinceArr.count; i++) {
        
        NSDictionary * provinceDic = provinceArr[i];
        Province * province = [[Province alloc] init];
        province.province = provinceDic[@"province"];
        
        NSArray * cityArr = provinceDic[@"city"];
        for (int j = 0; j < cityArr.count; j++) {
            
            NSDictionary * cityDic = cityArr[j];
            City * city = [[City alloc] init];
            city.city = cityDic[@"city"];
            
            NSArray * districtArr = cityDic[@"district"];
            for (int k = 0; k < districtArr.count; k++) {
                
                District * district = [[District alloc] init];
                district.district = districtArr[k];
                [city.districtArr addObject:district];
            }
            [province.cityArr addObject:city];
        }
        
        [self.placeArr addObject:province];
    }
    
    Province * province = _placeArr.firstObject;
    City * city = province.cityArr.firstObject;
    District * district = city.districtArr.firstObject;
    
    [self.view_menu configViewWithProvince:province.province city:city.city district:district.district];
}

#pragma mark - add subviews

- (void)addSubviews {
    
    [self.view addSubview:self.view_place];
    [self.view addSubview:self.view_menu];
    _view_place.hidden = YES;
}

#pragma mark - make constraints

- (void)makeConstraintsForUI {
    
    [_view_menu mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.height.mas_equalTo(@50);
        make.left.mas_equalTo(@0);
        make.right.mas_equalTo(@0);
        make.top.mas_equalTo(@64);
    }];
    
    [_view_place mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.left.mas_equalTo(@0);
        make.top.mas_equalTo(_view_menu.mas_bottom);
        make.bottom.mas_equalTo(@0);
        make.right.mas_equalTo(@0);
    }];
}

#pragma mark - pickView delegate

- (void)menuView:(PickPlaceMenu *)menuView didSelectAtIndex:(NSInteger)index isShow:(BOOL)isShow {
    
    if (index == 0) {
        
        if (isShow) {
            
            _view_place.hidden = NO;
            
            NSMutableArray * provinceArr = [[NSMutableArray alloc] init];
            for (int i = 0; i < self.placeArr.count; i++) {
                
                Province * province = _placeArr[i];
                [provinceArr addObject:province.province];
            }
            [_view_place reloadViewWithData:provinceArr component:0];
        } else {
            
            [_view_place hide];
        }
    } else if (index == 1) {
        
        if (isShow) {
            
            _view_place.hidden = NO;
            Province * province = _placeArr[_provinceIndex];
            NSMutableArray * cityArr = [[NSMutableArray alloc] init];
            for (int i = 0; i < province.cityArr.count; i++) {
                
                City * city = province.cityArr[i];
                [cityArr addObject:city.city];
            }
            [_view_place reloadViewWithData:cityArr component:1];
        } else {
            
            [_view_place hide];
        }
    } else {
        
        if (isShow) {
            
            _view_place.hidden = NO;
            Province * province = _placeArr[_provinceIndex];
            City * city = province.cityArr[_cityIndex];
            NSMutableArray * districtArr = [[NSMutableArray alloc] init];
            for (int i = 0; i < city.districtArr.count; i++) {
                
                District * district = city.districtArr[i];
                [districtArr addObject:district.district];
            }
            [_view_place reloadViewWithData:districtArr component:2];
        } else {
            
            [_view_place hide];
        }
    }
}

#pragma mark - placeView delegate

- (void)placeView:(PickPlaceView *)placeView didSelectPlace:(NSString *)place atComponent:(NSInteger)component atRow:(NSInteger)row {
    
    if (component == 0) {
        
        if (_provinceIndex != row) {
            
            _provinceIndex = row;
            _cityIndex = 0;
            _districtIndex = 0;
            Province * province = _placeArr[row];
            City * city = province.cityArr.firstObject;
            District * district = city.districtArr.firstObject;
            [_view_menu configViewWithProvince:place city:city.city district:district.district];
        }
    } else if (component == 1) {
        
        if (_cityIndex != row) {
            
            _cityIndex = row;
            _districtIndex = 0;
            Province * province = _placeArr[_provinceIndex];
            City * city = province.cityArr[row];
            District * district = city.districtArr.firstObject;
            [_view_menu configViewWithProvince:nil city:place district:district.district];
        }
    } else {
        
        if (_districtIndex != row) {
            
            _districtIndex = row;
            [_view_menu configViewWithProvince:nil city:nil district:place];
        }
    }
    
    [_view_menu reset];
}

- (void)placeViewDidHide {
    
    [_view_menu reset];
}

#pragma mark - setter and getter

- (PickPlaceMenu *)view_menu {
    
    if (!_view_menu) {
        
        _view_menu = [[PickPlaceMenu alloc] init];
        _view_menu.delegate = self;
    }
    return _view_menu;
}

- (PickPlaceView *)view_place {
    
    if (!_view_place) {
        
        _view_place = [[PickPlaceView alloc] init];
        _view_place.delegate = self;
    }
    return _view_place;
}

- (NSMutableArray *)placeArr {
    
    if (!_placeArr) {
        
        _placeArr = [[NSMutableArray alloc] init];
    }
    return _placeArr;
}
@end

从使用上,可以清楚的看出,主要是在两个定制的view的代理方法中进行相互的刷新view操作,同时在代理方法中可以获取到我们需求的信息,即选择地区是属于哪一级的,以及每一级的当前选择是什么或者说每一级当前选择展示的id是什么。
这里也简单的将省/市/区、县做成了三级关联的model,这个大家可以根据需求自己创建。

demo下载地址:https://github.com/guorenhao/PickPlace

最后,希望能够帮助到有需要的猿友们,如果有哪里不清楚的地方或者建议,请提出,小编会在看到的第一时间给你回复。愿我们能够共同成长进步,在开发的道路上越走越远!谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容