iOS開發(fā)-實現(xiàn)地區(qū)選擇三級聯(lián)動

Map.png

前言:對于地區(qū)的選擇使用的地方還是比較多的隙袁,而地區(qū)選擇的使用一般都是伴隨著聯(lián)動,常用的二級和三級的聯(lián)動效果比較多一些抛腕。今天小編給大家主要介紹一下地區(qū)選擇三級聯(lián)動的實現(xiàn)服赎。相信大家會了三級的聯(lián)動效果,那么二級聯(lián)動就是信手拈來了梁沧。

原理:使用代理傳值檀何。地區(qū)選擇的菜單欄和展示選擇區(qū)分開定制,同時通過代理方法將值和事件傳遞并進行相應(yīng)的view刷新。如果有興趣的朋友還可以把這兩個view合并到一個新的整體view中進行再次封裝频鉴。

首先栓辜,大家先來看一下效果圖

地區(qū)選擇三級聯(lián)動.gif

下面,我們先來創(chuàng)建地區(qū)選擇的菜單欄的view.h如下:

#import <UIKit/UIKit.h>

@protocol PickPlaceMenuDelegate;
@interface PickPlaceMenu : UIView

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

/**
 配置菜單

 @param province 省
 @param city     市
 @param district 區(qū)/縣
 */
- (void)configViewWithProvince:(NSString *)province city:(NSString *)city district:(NSString *)district;

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

//代理方法
@optional
/**
 點擊菜單

 @param menuView 菜單view
 @param index    選中菜單的下標(biāo):0代表省垛孔,1代表市藕甩,2代表區(qū)/縣
 @param isShow   是否彈出顯示當(dāng)前的對應(yīng)列表
 */
- (void)menuView:(PickPlaceMenu *)menuView didSelectAtIndex:(NSInteger)index isShow:(BOOL)isShow;
@end

所有方法和代理都給大家注釋了,這里不再多說周荐,接下來我們來看在.m中的布局及實現(xiàn)如下:

#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

大家可以看到狭莱,這里是用了三個按鈕來實現(xiàn)的菜單點擊效果,這個按鈕和布局概作,大家可以根據(jù)自己的需求進行相應(yīng)的修改腋妙,不過事件的處理和代理的賦值基本是不需要修改的。

接下來讯榕,我們繼續(xù)創(chuàng)建展示地區(qū)選擇列表的一個view.h如下:

#import <UIKit/UIKit.h>

@protocol PickPlaceViewDelegate;
@interface PickPlaceView : UIView

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

/**
 刷新展示地區(qū)的列表view

 @param dataArr   數(shù)據(jù)源:省/市/ 區(qū)骤素、縣
 @param component 菜單選中下標(biāo)(這里我稱之為列)
 */
- (void)reloadViewWithData:(NSArray *)dataArr component:(NSInteger)component;

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

// 代理方法
@optional

/**
 選中地區(qū)

 @param placeView 地區(qū)view
 @param place     選中的地區(qū)
 @param component 在菜單的第幾個(列)
 @param row       選中的在第幾行
 */
- (void)placeView:(PickPlaceView *)placeView didSelectPlace:(NSString *)place atComponent:(NSInteger)component atRow:(NSInteger)row;

/**
 展示地區(qū)view收起
 */
- (void)placeViewDidHide;

@end

這里也都添加了注釋,相信大家都能夠看的明白愚屁。我們繼續(xù)來看在.m中的實現(xiàn)如下:

#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來進行列表的展示济竹,并通過動畫來實現(xiàn)向下彈出和向上收起的動畫效果及半透明背景的漸變效果。每次調(diào)用外漏刷新數(shù)據(jù)方法時霎槐,列表刷新數(shù)據(jù)并向下彈出送浊,選中或者點擊空白地方時向上收起,同時回調(diào)該事件丘跌。以讓菜單欄也進行相應(yīng)的view的刷新罕袋。

封裝基本完成,下面我們來簡單看一下使用方法碍岔。
這里,我建了一個Header類才存儲所有的頭文件朵夏,使用時只需要導(dǎo)入該Header類就可以了蔼啦。為了使數(shù)據(jù)看起來更整潔,我簡單寫了一個城市地區(qū)的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 = @"地區(qū)選擇";
    
    [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操作鸵赫,同時在代理方法中可以獲取到我們需求的信息,即選擇地區(qū)是屬于哪一級的躏升,以及每一級的當(dāng)前選擇是什么或者說每一級當(dāng)前選擇展示的id是什么辩棒。
這里也簡單的將省/市/區(qū)、縣做成了三級關(guān)聯(lián)的model,這個大家可以根據(jù)需求自己創(chuàng)建一睁。

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

最后钻弄,希望能夠幫助到有需要的猿友們,如果有哪里不清楚的地方或者建議者吁,請?zhí)岢鼍桨常【帟诳吹降牡谝粫r間給你回復(fù)。愿我們能夠共同成長進步复凳,在開發(fā)的道路上越走越遠瘤泪!謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末育八,一起剝皮案震驚了整個濱河市对途,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌单鹿,老刑警劉巖掀宋,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仲锄,居然都是意外死亡劲妙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門儒喊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來镣奋,“玉大人,你說我怎么就攤上這事怀愧∏染保” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵芯义,是天一觀的道長哈垢。 經(jīng)常有香客問我,道長扛拨,這世上最難降的妖魔是什么耘分? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮绑警,結(jié)果婚禮上求泰,老公的妹妹穿的比我還像新娘。我一直安慰自己计盒,他們只是感情好渴频,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著北启,像睡著了一般卜朗。 火紅的嫁衣襯著肌膚如雪拔第。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天聊替,我揣著相機與錄音楼肪,去河邊找鬼。 笑死惹悄,一個胖子當(dāng)著我的面吹牛春叫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泣港,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼暂殖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了当纱?” 一聲冷哼從身側(cè)響起呛每,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坡氯,沒想到半個月后晨横,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡箫柳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年手形,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悯恍。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡库糠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涮毫,到底是詐尸還是另有隱情瞬欧,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布罢防,位于F島的核電站艘虎,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏咒吐。R本人自食惡果不足惜顷帖,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渤滞。 院中可真熱鬧,春花似錦榴嗅、人聲如沸妄呕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绪励。三九已至肿孵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疏魏,已是汗流浹背停做。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留大莫,地道東北人蛉腌。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像只厘,于是被迫代替她去往敵國和親烙丛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容