iOS自定义BBAlertViewController

〇、目地

为什么会选择设计BBAlertViewController组件呢?主要有两个重要的原因:一、就目前项目而言,目前项目中维护了20多个不同种类的Alert弹框,维护起来确实耗时耗力,结果不尽人意;二、新项目开发过程中避免第一种情况再次发生,而又能多功能复用的控件。基于这两个重要原因,所以花了一点时间设计自定义的BBViewController组件。

一、功能介绍

自定义BBAlertViewController组件主要实现在项目中并存多个自定义的情况,可以删除更多关于弹框的冗余代码,实现更高效、更高自主的弹框方式,主要功能如下:

  • 1、经典的BBAlertControlleriOS Native显示模式无异。结合BBAlertViewController可以更好衔接原生的开发,一旦项目中AlertViewController样式变动,只需要把对应的中间工具类一变,即可以实现需求,完美而又快捷。
  • 2、可以根据项目主色调整BBAlertViewController中的任意一个色值。可以根据组件提供的属性实现各种UI的展示,不需要去处理一行适应的代码,让开发变得更简单。
  • 3、高度自定义BBAlertViewController显示样式。可以根据自已的UI界面,呈现出各种不一样的AlertViewController,轻松应付UI设计,如:弹框中需在加入背景图片、每个按钮都有一个不同的图标、需要在AlertViewController里面实现文字与图片的布局等等。
  • 4、实现插桩模式的自定义BBAlertViewController弹框。可以通过外部代码控制我们AlertViewController中的显示,可以通过点击AlertViewController中的按钮获取自已框里同的值,可以在外部直接通过Masonry布局,让开发者神往的小工具。

二、设计思路

自定义BBAlertViewController实现采用的语言是Objective-C,设计思路参考了iOS中的WKWebView设计方案,采用单独的配置文件实现所有的属性与功能配置。界面展示采用NativeUIAlertController,以ViewController为宿主,减少内存实例化过多的问题。
首先、BBAlertViewController的弹框模式

+ (instancetype)alertViewControllerWithTitle:(NSString *)title withMessage:(NSString *)message  withConfiguration:(nonnull BBAlertConfiguration *)alertConfiguration {
    BBAlertViewController *instance = [[self alloc] init];
//   因为现在加入自定义东西,所以有的时候不能处理
//    if (title.length < 1 && message.length < 1) {
//        NSAssert(NO, @"Title和Message必须有一个有值");
//    }
    //这个必须放在最前面,不然不能正常执行到
    instance.alertConfiguration = alertConfiguration;
    instance.titleString = title;
    instance.messageString = message;
    //设置view.backgroundColor就已经开始执行viewDidLoad方法
    instance.view.backgroundColor = [UIColor colorWithHex:0x333333 alpha:0.5f];
    instance.modalPresentationStyle =  UIModalPresentationOverCurrentContext;
    return instance;
}

其次、整个BBAlertViewController的所有设置的属性统一在BBAlertConfiguration类中,有两个好处:一、统一管理属性;二、属性与ViewController分开(实现原理如NSURLSession/WKWebView一致)。

三、项目使用

1、直接从GITHUB中下载代码到当前项目中,git地址:https://gitee.com/MiBao12/BBAlertViewController

2、封装专门的弹框类库,如:

#import "BBAlertViewTools.h"
#import "BBAlertViewController.h"
#import "BBAlertConfiguration.h"
#import "BBAlertAction.h"

@interface BBAlertViewTools ()

@end

@implementation BBAlertViewTools


+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:@"" withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewConroller:(UIViewController *)viewConroller withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:viewConroller withMessage:@"" withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewDefaultWithMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:@"温馨提示" withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewDefaultWithMessage:(NSString *)message withViewController:(UIViewController*)viewController  withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:@"温馨提示" withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:@"" withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewWithMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:@"" withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewWithMessage:(NSString *)message withViewController:(UIViewController*)viewController  withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:@"" withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewController:(UIViewController*)viewController withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
      
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle  withMessage:(NSString *)message withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(void))eventBlock {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:nil withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
        if (eventBlock) {
            eventBlock();
        }
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewController:(UIViewController*)viewController  withMessage:(NSString *)message withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(void))eventBlock {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:viewController withMessage:message withConfirmTitle:nil withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
        if (eventBlock) {
            eventBlock();
        }
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withEventBlock:(void(^)(void))eventBlock {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
        if (eventBlock) {
            eventBlock();
        }
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewConroller:(UIViewController *)viewController  withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withEventBlock:(void(^)(void))eventBlock {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:viewController withMessage:message withConfirmTitle:confirmTitle withCancelTitle:nil withEventBlock:^(NSInteger index) {
        if (eventBlock) {
            eventBlock();
        }
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withViewConroller:(UIViewController *)viewController withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
    BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
    defaultConfiguration.verticalHidden = YES;
    defaultConfiguration.acrossHidden = YES;
    defaultConfiguration.actionDirection = BBActionDirectionDefault;
    defaultConfiguration.typeDefaultBackgroundColor = BB_MainColor;
    defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
    defaultConfiguration.typeCancelBackgroundColor = BB_HexColor(0xffffff);
    defaultConfiguration.cancelBorderColor = BB_MainColor;
    defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
    defaultConfiguration.defaultBorderColor = BB_MainColor;
    defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
    defaultConfiguration.actionHeight = 40.f;
    defaultConfiguration.actionCornerRadius = 8.f;
    
    BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:alertTitle withMessage:message withConfiguration:defaultConfiguration];
    BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(1);
        }
    }];
    BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(0);
        }
    }];
    if (confirmTitle != nil && confirmTitle.length > 0) {
        [alertViewController addAction:confirmAlertAction];
    }
    if (cancelTitle != nil && cancelTitle.length > 0) {
        [alertViewController addAction:cancelAlertAction];
    }
    
    UIViewController *tempViewController = viewController;
    if (viewController == nil) {
        tempViewController = [BBUICommonTools findCurrentShowingViewController];
      
        if (tempViewController.tabBarController != nil) {
            tempViewController = tempViewController.tabBarController;
        }
    }
    [tempViewController presentViewController:alertViewController animated:NO completion:^{
            
    }];
}

+ (void)alertViewWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
    [self alertViewWithAlertTitle:alertTitle withViewConroller:nil withMessage:message withConfirmTitle:confirmTitle   withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
        if (eventBlock) {
            eventBlock(index);
        }
    }];
}

+ (void)alertViewVerticalWithAlertTitle:(NSString *)alertTitle withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
    BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
    defaultConfiguration.verticalHidden = YES;
    defaultConfiguration.acrossHidden = YES;
    defaultConfiguration.actionDirection = BBActionDirectionVertical;
    
    defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
    
    defaultConfiguration.typeCancelBackgroundColor = BB_MainColor;
    defaultConfiguration.cancelBorderColor = BB_MainColor;
    defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
    defaultConfiguration.typeCancelColor = [UIColor whiteColor];
    
    defaultConfiguration.defaultBorderColor = BB_MainColor;
    defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
    defaultConfiguration.typeDefaultBackgroundColor = [UIColor whiteColor];
    defaultConfiguration.typeDefaultColor = BB_MainColor;
    
    defaultConfiguration.actionHeight = 40.f;
    defaultConfiguration.actionCornerRadius = 8.f;
    
    BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:alertTitle withMessage:message withConfiguration:defaultConfiguration];
    BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(1);
        }
    }];
    BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(0);
        }
    }];
    if (confirmTitle != nil && confirmTitle.length > 0) {
        [alertViewController addAction:confirmAlertAction];
    }
    if (cancelTitle != nil && cancelTitle.length > 0) {
        [alertViewController addAction:cancelAlertAction];
    }
    UIViewController *tempViewController = [BBUICommonTools findCurrentShowingViewController];
    if (tempViewController.tabBarController != nil) {
        tempViewController = tempViewController.tabBarController;
    }
    [tempViewController presentViewController:alertViewController animated:NO completion:^{
            
    }];
}

+ (void)alertViewCustomMessageViewWithAlertTitle:(NSString *)alertTitle withMessageView:(UIView *)messageView withLayerUIBlock:(void(^)(void))layerUIBlock withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
    [self alertViewCustomMessageViewWithAlertTitle:alertTitle withViewController:nil withMessageView:messageView withLayerUIBlock:layerUIBlock withConfirmTitle:confirmTitle withCancelTitle:cancelTitle withEventBlock:^(NSInteger index) {
        if (eventBlock) {
            eventBlock(index);
        }
    }];
}


+ (void)alertViewCustomMessageViewWithAlertTitle:(NSString *)alertTitle withViewController:(UIViewController *)viewController withMessageView:(UIView *)messageView withLayerUIBlock:(void(^)(void))layerUIBlock withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
    BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
    defaultConfiguration.verticalHidden = YES;
    defaultConfiguration.acrossHidden = YES;
    defaultConfiguration.actionDirection = BBActionDirectionDefault;
    defaultConfiguration.typeDefaultBackgroundColor = BB_MainColor;
    defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
    defaultConfiguration.typeCancelBackgroundColor = BB_HexColor(0xffffff);
    defaultConfiguration.cancelBorderColor = BB_MainColor;
    defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
    defaultConfiguration.defaultBorderColor = BB_MainColor;
    defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
    defaultConfiguration.actionHeight = 40.f;
    defaultConfiguration.actionCornerRadius = 8.f;
    
    BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:alertTitle withMessage:@"" withConfiguration:defaultConfiguration];
    BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(1);
        }
    }];
    BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(0);
        }
    }];
    if (confirmTitle != nil && confirmTitle.length > 0) {
        [alertViewController addAction:confirmAlertAction];
    }
    if (cancelTitle != nil && cancelTitle.length > 0) {
        [alertViewController addAction:cancelAlertAction];
    }
    alertViewController.customContentView = messageView;
    alertViewController.customLayer = layerUIBlock;
    UIViewController *tempViewController = viewController;
    if (tempViewController == nil) {
        tempViewController = [BBUICommonTools findCurrentShowingViewController];
    }
    if (tempViewController.tabBarController != nil) {
        tempViewController = tempViewController.tabBarController;
    }
    [tempViewController presentViewController:alertViewController animated:NO completion:^{
        
    }];
}

+ (void)alertViewCustomWithAlertTitle:(NSString *)alertTitle withMessageIcon:(NSString *)messageIconName withMessage:(NSString *)message withConfirmTitle:(NSString *)confirmTitle withCancelTitle:(NSString *)cancelTitle withEventBlock:(void(^)(NSInteger index))eventBlock {
    UIImageView *iconImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:messageIconName]];
    UILabel *titleLabel = [UILabel labelWithText:alertTitle withTextColor:BB_HexColor(0x000000) withFont:BB_RelativeBoldFont(18.f)];
    UILabel *descLabel = [UILabel labelWithText:message withTextColor:BB_HexColor(0x666666) withFont:BB_RelativeFont(13.f)];
//    descLabel.textAlignment = NSTextAlignmentCenter;
    UIView *customView = [[UIView alloc] init];
    [customView addSubview:iconImageView];
    [customView addSubview:titleLabel];
    [customView addSubview:descLabel];
    
    BBAlertConfiguration *defaultConfiguration = [BBAlertConfiguration defaultAlertViewConfiguration];
    defaultConfiguration.verticalHidden = YES;
    defaultConfiguration.acrossHidden = YES;
    defaultConfiguration.actionDirection = BBActionDirectionDefault;
    defaultConfiguration.typeDefaultBackgroundColor = BB_MainColor;
    defaultConfiguration.actionEdgeInsets = UIEdgeInsetsMake(10,20, 30, 20);
    defaultConfiguration.typeCancelBackgroundColor = BB_HexColor(0xffffff);
    defaultConfiguration.typeCancelColor = BB_HexColor(0x999999);
    defaultConfiguration.cancelBorderColor = BB_HexColor(0x999999);
    defaultConfiguration.cancelBorderWidth = BB_Relative(1.f);
    defaultConfiguration.defaultBorderColor = BB_MainColor;
    defaultConfiguration.defaultBorderWidth = BB_Relative(1.f);
    defaultConfiguration.actionHeight = 40.f;
    defaultConfiguration.actionCornerRadius = 8.f;
    
    BBAlertViewController *alertViewController = [BBAlertViewController alertViewControllerWithTitle:@"" withMessage:@"" withConfiguration:defaultConfiguration];
    BBAlertAction *confirmAlertAction = [BBAlertAction alertActionWithActionTitle:confirmTitle withActionType:BBAlertActionTypeDefault withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(1);
        }
    }];
    BBAlertAction *cancelAlertAction = [BBAlertAction alertActionWithActionTitle:cancelTitle withActionType:BBAlertActionTypeCancel withActionIconImage:nil withActionEdgeInsetStyle:BBAlertActionEdgeInsetsStyleLeft withTextAndImageSpace:5.f withActionBlock:^{
        if (eventBlock) {
            eventBlock(0);
        }
    }];
    if (confirmTitle != nil && confirmTitle.length > 0) {
        [alertViewController addAction:confirmAlertAction];
    }
    if (cancelTitle != nil && cancelTitle.length > 0) {
        [alertViewController addAction:cancelAlertAction];
    }
    alertViewController.customContentView = customView;
    alertViewController.customLayer = ^{
        [customView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.left.right.bottom.offset(0);
        }];
        [iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.offset(0);
            make.centerX.equalTo(customView.mas_centerX).offset(0);
            make.width.height.offset(BB_Relative(78));
        }];
        [titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerX.equalTo(customView.mas_centerX).offset(0);
            make.top.equalTo(iconImageView.mas_bottom).offset(BB_Relative(7));
        }];
        [descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(titleLabel.mas_bottom).offset(BB_Relative(15));
            make.left.offset(BB_Relative(12));
            make.right.offset(-BB_Relative(12));
            make.bottom.offset(-BB_Relative(12));
        }];
    };
    UIViewController *tempViewController = [BBUICommonTools findCurrentShowingViewController];
    if (tempViewController.tabBarController != nil) {
        tempViewController = tempViewController.tabBarController;
    }
    [tempViewController presentViewController:alertViewController animated:NO completion:^{
        
    }];
}
@end

四、功能优化点

目前弹框处有一点小的问题,同时发起一个以上的弹框,只能弹出一个,后续将优化。

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

推荐阅读更多精彩内容