iOS 圆环菜单

前言

之前的一个项目,没有使用TabBar,而是选择用圆环作为用户点击的菜单,加上深蓝的冷色调,APP看着还蛮高大上,先看下效果图:


demo.gif

效果图分析

1.类似地球的是一张Image,其余的都是Button,每个button都是可以点击,点击回调至VC你可以处理一些事.
2.项目中的需求是旋转圆盘后自动会停止,停止时布局还是和最开始的一样(只不过可能不是原来的按钮),点击某个按钮,这个按钮就在最上方的中间处.
3.点击中间的按钮,圆盘能缩放,再次点击时显示.

实现

.h文件

这个文件定义一个回调block以及初始化view和传入数据的方法

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

typedef void(^clickSomeOne)(NSString *str);

@interface LWCustomCircleView : UIView

//在想要回传的界面中定义,block必须用copy来修饰
@property (nonatomic, copy) clickSomeOne clickButton;

- (id)initWithFrame:(CGRect)frame andImage:(UIImage *)image;

- (void)addSubviewWithSubView:(NSArray *)imageArray andTitle:(NSArray *)titleArray andSize:(CGSize)size andCenterImage:(UIImage *)centerImage;

@end

.m文件

定义的属性,注释的很清楚
@interface LWCustomCircleView()

/** 播放音效 */
@property (nonatomic, assign) SystemSoundID soundID;
/** 减速定时器 */
@property (nonatomic, strong) NSTimer *timer;
/** 子试图数量 */
@property (nonatomic, assign) CGFloat numOfSubView;
/** 圆形图 */
@property (nonatomic, strong) UIImageView *circleImage;
/** 减速定时器 */
@property (nonatomic, strong) UIImageView *arrowImage;
/** 子试图数组 */
@property (nonatomic, strong) NSMutableArray *subViewArray;
/** 按钮数组 */
@property (nonatomic, strong) NSMutableArray *buttonArray;
/** 第一触碰点 */
@property (nonatomic, assign) CGPoint beginPoint;
/** 第二触碰点 */
@property (nonatomic, assign) CGPoint movePoint;
/** 正在跑 */
@property (nonatomic, assign) BOOL isPlaying;
/** 滑动时间 */
@property (nonatomic, strong) NSDate *date;
/** 开始转动时间 */
@property (nonatomic, strong) NSDate *startTouchDate;
/** 减速计数 */
@property (nonatomic, assign) NSInteger decelerTime;
/** 子试图大小 */
@property (nonatomic, assign) CGSize subViewSize;
/** 滑动手势 */
@property (nonatomic, strong) UIPanGestureRecognizer *panGes;
/** 转动的角度 */
@property (nonatomic, assign) double mStartAngle;
/** 转动临界速度,超过此速度便是快速滑动,手指离开仍会转动 */
@property (nonatomic, assign) int mFlingableValue;
/** 半径 */
@property (nonatomic, assign) int mRadius;
/** 检测按下到抬起时旋转的角度 */
@property (nonatomic, assign) float mTmpAngle;
/** 顺时针转动的定时器 */
@property (nonatomic, strong) NSTimer *flowtime;
/**逆时针转动的定时器 */
@property (nonatomic, strong) NSTimer *reverseTime;
@property (nonatomic, assign) float anglePerSecond;
/** 转动速度 */
@property (nonatomic, assign) float speed;

@end
初始化视图和一些属性
- (id)initWithFrame:(CGRect)frame andImage:(UIImage *)image
{
    if (self = [super initWithFrame:frame]) {
        self.decelerTime = 0;
        self.subViewArray = [[NSMutableArray alloc] init];
        self.circleImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
        
        if (image == nil) {
            self.circleImage.layer.cornerRadius = frame.size.width / 2;
        }else {
            self.circleImage.image = image;
            self.circleImage.backgroundColor = [UIColor clearColor];
        }
        self.mRadius = frame.size.width / 2;
        self.mStartAngle = M_PI_2 * 3;
        self.mFlingableValue = 300;
        self.isPlaying = false;
        self.circleImage.userInteractionEnabled = YES;
        [self addSubview:self.circleImage];
        
    }
    return self;
}

按钮的布局

给按钮添加图片和文字,中间的按钮只添加图片,添加滑动的手势和点击按钮时的重新布局

- (void)addSubviewWithSubView:(NSArray *)imageArray andTitle:(NSArray *)titleArray andSize:(CGSize)size andCenterImage:(UIImage *)centerImage
{
    self.subViewSize = size;
    self.numOfSubView = (CGFloat)titleArray.count;
    self.buttonArray = [[NSMutableArray alloc] init];
    
    for (NSInteger i = 0; i < self.numOfSubView; i++) {
        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(20*Width, 20*Width, size.width*Width, size.height*Height)];
        [button setImage:imageArray[i] forState:UIControlStateNormal];
        //设置image在button上的位置(上top,左left,下bottom,右right)这里可以写负值,对上写-5,那么image就象上移动5个像素
        [button setTitle:titleArray[i] forState:UIControlStateNormal];
        [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        button.titleLabel.font = [UIFont systemFontOfSize:16*Width];
        button.titleLabel.textAlignment = NSTextAlignmentCenter;
        button.imageEdgeInsets = UIEdgeInsetsMake(8,8,8,button.titleLabel.bounds.size.width);
        button.titleEdgeInsets = UIEdgeInsetsMake(70, -button.imageView.bounds.size.width-40, 0, 0);
        [button addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
        button.tag = 100 + i;
        
        [self.buttonArray addObject:button];
        [self.subViewArray addObject:button];
        [self.circleImage addSubview:button];
    }
    //按钮布局
    [self layoutButton];
    
    //中间按钮
    UIButton *centerBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width/3.0, self.frame.size.height/3.0)];
    centerBtn.tag = 100 + self.numOfSubView + 1;
    centerBtn.layer.cornerRadius = self.frame.size.width / 6.0;
    [centerBtn setImage:centerImage forState:UIControlStateNormal];
    centerBtn.center = CGPointMake(self.frame.size.width/2.0, self.frame.size.height / 2.0);
    [centerBtn addTarget:self action:@selector(clickBtnCenter:) forControlEvents:UIControlEventTouchUpInside];
    [self.subViewArray addObject:centerBtn];
    [self.circleImage addSubview:centerBtn];
    
    //转动手势
    self.panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(zhuanPgr:)];
    [self.circleImage addGestureRecognizer:self.panGes];
    
    //加点击效果
    for (NSInteger i=0; i<self.subViewArray.count; i++) {
        UIButton *button= self.subViewArray[i];
        [button addTarget:self action:@selector(subViewOut:) forControlEvents:UIControlEventTouchUpInside];
    }
}
按钮的布局

按钮分布在圆环上,这里用到正弦和余弦函数

//按钮布局
- (void)layoutButton
{
    /**
     M_PI   pi    3.14159265358979323846
     M_PI_2 pi/2  1.57079632679489661923
     M_PI_4 pi/4  0.785398163397448309616
     */
    /**
     sin((i/self.numOfSubView) * M_PI * 2 + self.mStartAngle):布局滑动时按钮均匀分布在圆的各个位置
     (self.frame.size.width/2 -  self.subViewSize.width/2 - 20):让按钮布局在圆环间
     */
    for (NSInteger i = 0; i < self.numOfSubView; i++) {
        CGFloat yy = 195 + sin((i/self.numOfSubView) * M_PI * 2 + self.mStartAngle) * (self.frame.size.width/2 - self.subViewSize.width/2 - 30);
        CGFloat xx = 195 + cos((i/self.numOfSubView) * M_PI * 2 + self.mStartAngle) * (self.frame.size.width/2 - self.subViewSize.width/2 - 30);
        UIButton *button = [self.buttonArray objectAtIndex:i];
        button.center = CGPointMake(xx, yy);
    }
    
}
滑动手势的处理

代码中的注释很详细

-(void)zhuanPgr:(UIPanGestureRecognizer *)pgr
{
    if (pgr.state == UIGestureRecognizerStateBegan) {
        self.mTmpAngle = 0;
        self.beginPoint = [pgr locationInView:self];
        self.startTouchDate = [NSDate date];
    }else if (pgr.state == UIGestureRecognizerStateChanged) {
        float StartAngleLast = self.mStartAngle;
        self.movePoint = [pgr locationInView:self];
        float start = [self getAngle:self.beginPoint];
        float end = [self getAngle:self.movePoint];
        if ([self getQuadrant:self.movePoint] == 1 || [self getQuadrant:self.movePoint] == 4) {
            //一、四象限
            self.mStartAngle += end - start;
            self.mTmpAngle += end - start;
            
        }else {
            //二三象限
            self.mStartAngle += start - end;
            self.mTmpAngle += start - end;
        }
        [self layoutButton];
        self.beginPoint = self.movePoint;
        self.speed = self.mStartAngle - StartAngleLast;
        
        NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:self.startTouchDate];
        self.anglePerSecond = self.mTmpAngle * 50 / time;
        
    }else if (pgr.state == UIGestureRecognizerStateEnded) {
        //计算每秒转动的角度
        NSTimeInterval time = [[NSDate date] timeIntervalSinceDate:self.startTouchDate];
        self.anglePerSecond = self.mTmpAngle * 50 / time;
        
        if (self.anglePerSecond > 0) {
            //求绝对值的函数,顺时针转动
            if (fabs(self.anglePerSecond) > self.mFlingableValue && !self.isPlaying) {
                self.isPlaying = true;
                self.flowtime = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(flowAction) userInfo:nil repeats:YES];
                [[NSRunLoop currentRunLoop] addTimer:self.flowtime forMode:NSRunLoopCommonModes];
            }
        }else {
            //逆时针转动
            if (-fabsf(self.anglePerSecond) < -self.mFlingableValue && !self.isPlaying) {
                
                self.isPlaying = true;
                self.reverseTime = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(reverseAction) userInfo:nil repeats:YES];
                [[NSRunLoop currentRunLoop] addTimer:self.reverseTime forMode:NSRunLoopCommonModes];
            }
        }
        
        if (self.isPlaying == false){
            if (self.mStartAngle >= 0){
                //fmod是取两个数相除的余数
                if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*2.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*3+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*3;
                    [self layoutButton];
                    self.clickButton(@"100");
                }
                if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*1.68+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*2.32+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*2.32;
                    [self layoutButton];
                    self.clickButton(@"101");
                }
                if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*1+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)<=M_PI_2*1.68+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*1.68;
                    [self layoutButton];
                    self.clickButton(@"102");
                }
                if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*0.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)<=M_PI_2*1+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*1;
                    [self layoutButton];
                    self.clickButton(@"103");
                }
                if (fmod(self.mStartAngle, M_PI*2) > 0 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*0.32+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*0.32;
                    [self layoutButton];
                    self.clickButton(@"104");
                }
                if (fmod(self.mStartAngle, M_PI*2)-M_PI*2 <= 0 && fmod(self.mStartAngle, M_PI*2)-M_PI*2 >= -M_PI_2*0.32*2) {
                    //        mStartAngle = M_PI_2*3.66;
                    self.mStartAngle = -M_PI_2*0.32;
                    [self layoutButton];
                    self.clickButton(@"105");
                }
                
            }else {
                
                if (fmod(self.mStartAngle, M_PI*2)+M_PI*2 > M_PI_2*2.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2<=M_PI_2*3+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*3;
                    [self layoutButton];
                    self.clickButton(@"100");
                }
                if (fmod(self.mStartAngle, M_PI*2)+M_PI*2 > M_PI_2*1.68+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2<=M_PI_2*2.32+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*2.32;
                    [self layoutButton];
                    self.clickButton(@"101");
                }
                if (fmod(self.mStartAngle, M_PI*2)+M_PI*2 > M_PI_2*1+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2<=M_PI_2*1.68+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*1.68;
                    [self layoutButton];
                    self.clickButton(@"102");
                }
                if (fmod(self.mStartAngle, M_PI*2)+M_PI*2 > M_PI_2*0.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2<=M_PI_2*1+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*1;
                    [self layoutButton];
                    self.clickButton(@"103");
                }
                if (fmod(self.mStartAngle, M_PI*2)+M_PI*2 > 0+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2<=M_PI_2*0.32+M_PI_2*0.32) {
                    self.mStartAngle = M_PI_2*0.32;
                    [self layoutButton];
                   self.clickButton(@"104");
                }
                if (fmod(self.mStartAngle, M_PI*2) <= 0 && fmod(self.mStartAngle, M_PI*2) >= -M_PI_2*0.32*2) {
                    //        mStartAngle = M_PI_2*3.66;
                    self.mStartAngle = -M_PI_2*0.32;
                    [self layoutButton];
                    self.clickButton(@"105");
                }
            }
        }
        
        
    }
}

//获取当前点弧度
/**
 hypot:计算直角三角形的斜边长
 */
-(float)getAngle:(CGPoint)point {
    double x = point.x - self.mRadius;
    double y = point.y - self.mRadius;
    return (float) (asin(y / hypot(x, y)));
}

/** 根据当前位置计算象限 */
-(int) getQuadrant:(CGPoint) point {
    int tmpX = (int) (point.x - self.mRadius);
    int tmpY = (int) (point.y - self.mRadius);
    if (tmpX >= 0) {
        return tmpY >= 0 ? 1 : 4;
    } else {
        return tmpY >= 0 ? 2 : 3;
    }
}
顺时针和逆时针转动的定时器处理

速度减为零时,按钮重新布局,并销毁定时器

- (void)flowAction
{
    if (self.speed < 0.1) {
        [UIView animateWithDuration:2 animations:^{
            
        } completion:^(BOOL finished) {
            
        }];
        self.isPlaying = false;
        [self.flowtime invalidate];
        self.flowtime = nil;
        //停止转动时,布局好按钮位置,不需要这样的效果可注释
        if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*2.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*3+M_PI_2*0.32) {
            self.mStartAngle = M_PI_2*3;
            [self layoutButton];
            self.clickButton(@"100");
        }
        if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*1.68+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*2.32+M_PI_2*0.32) {
            self.mStartAngle = M_PI_2*2.32;
            [self layoutButton];
            self.clickButton(@"101");
        }
        if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*1+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*1.68+M_PI_2*0.32) {
            self.mStartAngle = M_PI_2*1.68;
            [self layoutButton];
            self.clickButton(@"102");
        }
        if (fmod(self.mStartAngle, M_PI*2) > M_PI_2*0.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*1+M_PI_2*0.32) {
            self.mStartAngle = M_PI_2*1;
            [self layoutButton];
            self.clickButton(@"103");
        }
        if (fmod(self.mStartAngle, M_PI*2) > 0 && fmod(self.mStartAngle, M_PI*2) <= M_PI_2*0.32+M_PI_2*0.32) {
            self.mStartAngle = M_PI_2*0.32;
            [self layoutButton];
           self.clickButton(@"104");
        }
        if (fmod(self.mStartAngle, M_PI*2)-M_PI*2 <= 0 && fmod(self.mStartAngle, M_PI*2)-M_PI*2 >= -M_PI_2*0.32*2) {
            //        mStartAngle = M_PI_2*3.66;
            self.mStartAngle = -M_PI_2*0.32;
            [self layoutButton];
            self.clickButton(@"105");
        }
        return;
        
    }
    
    // 不断改变mStartAngle,让其滚动,/30为了避免滚动太快
    self.mStartAngle += self.speed ;
    self.speed = self.speed/1.1;
    // 逐渐减小这个值
    //    anglePerSecond /= 1.1;
    [self layoutButton];
}

- (void)reverseAction
{
    
    if (self.speed > -0.1) {
        [UIView animateWithDuration:2 animations:^{

        } completion:^(BOOL finished) {

        }];
        self.isPlaying = false;
        [self.reverseTime invalidate];
        self.reverseTime = nil;
        //停止转动时,布局好按钮位置,不需要这样的效果可注释
        if ((fmod(self.mStartAngle, M_PI*2)+M_PI*2 > M_PI_2*2.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2 <= M_PI_2*3+M_PI_2*0.32) || (fmod(self.mStartAngle, M_PI*2)>M_PI_2*2.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)<=M_PI_2*3+M_PI_2*0.32)) {
            self.mStartAngle = M_PI_2*3;
            [self layoutButton];
            self.clickButton(@"100");
        }
        if ((fmod(self.mStartAngle, M_PI*2)+M_PI*2>M_PI_2*1.68+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2<=M_PI_2*2.32+M_PI_2*0.32)||(fmod(self.mStartAngle, M_PI*2)>M_PI_2*1.68+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)<=M_PI_2*2.32+M_PI_2*0.32)) {
            self.mStartAngle = M_PI_2*2.32;
            [self layoutButton];
            self.clickButton(@"101");
        }
        if ((fmod(self.mStartAngle, M_PI*2)+M_PI*2>M_PI_2*1+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2<=M_PI_2*1.68+M_PI_2*0.32)||(fmod(self.mStartAngle, M_PI*2)>M_PI_2*1+M_PI_2*0.32&&fmod(self.mStartAngle, M_PI*2)<=M_PI_2*1.68+M_PI_2*0.32)) {
            self.mStartAngle = M_PI_2*1.68;
            [self layoutButton];
            self.clickButton(@"102");
        }
        if ((fmod(self.mStartAngle, M_PI*2)+M_PI*2 > M_PI_2*0.32+M_PI_2*0.32 && fmod(self.mStartAngle, M_PI*2)+M_PI*2 <= M_PI_2*1+M_PI_2*0.32) || (fmod(self.mStartAngle, M_PI*2) > M_PI_2*0.32+M_PI_2*0.32&&fmod(self.mStartAngle, M_PI*2) <= M_PI_2*1+M_PI_2*0.32)) {
            self.mStartAngle = M_PI_2*1;
            [self layoutButton];
            self.clickButton(@"103");
        }
        if ((fmod(self.mStartAngle, M_PI*2)+M_PI*2>0 && fmod(self.mStartAngle, M_PI*2)+M_PI*2 <= M_PI_2*0.32+M_PI_2*0.32)||(fmod(self.mStartAngle, M_PI*2)>0&&fmod(self.mStartAngle, M_PI*2)<=M_PI_2*0.32+M_PI_2*0.32)) {
            self.mStartAngle = M_PI_2*0.32;
            [self layoutButton];
            self.clickButton(@"104");
        }
        if (fmod(self.mStartAngle, M_PI*2)<=0 && fmod(self.mStartAngle, M_PI*2) >= -M_PI_2*0.32*2) {
            //        mStartAngle = M_PI_2*3.66;
            self.mStartAngle = -M_PI_2*0.32;
            [self layoutButton];
            self.clickButton(@"105");
        }
        return;
    }
    
    self.mStartAngle += self.speed;
    self.speed = self.speed/1.1;
    
    [self layoutButton];
}

demo已上传至GitHub:https://github.com/CodeFeel/circleMenu

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,982评论 4 60
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,263评论 25 707
  • 背景 由于工作需要,研究了一下关于移动端直播的实现方式。现在市场上有一些比较成熟的嵌入微信或者其他移动平台的直播系...
    syncwt阅读 15,337评论 3 12
  • 曾经的美好如今成了记忆 过往的时光留下的是遗憾 想那白云悠悠 想那花果飘香 想那神仙府第 想那会宁红旗 开始是一个...
    夜行人郭小林阅读 227评论 0 0
  • 相信很多人和我一样吧。似乎每天都在寻找感兴趣的工作,对现在的工作只有深深的厌倦,期待下一次跳槽。 “做自己想做的事...
    尤物姑姑阅读 559评论 5 3