代碼處理iOS橫豎屏

1.監聽屏幕旋轉方向

在處理iOS橫豎屏時,經常會和UIDeviceOrientation、UIInterfaceOrientation和UIInterfaceOrientationMask這三個每局類型打交道,他們會從不同角度描述屏幕旋轉方向。

1->UIDeviceOrientation:設備方向

iOS的設備方向是通過iOS的加速計來獲取的

1.1->iOS定義了以下七種設備方向

typedef NS_ENUM(NSInteger, UIDeviceOrientation) {

UIDeviceOrientationUnknown,? ? ? ? ? ? ? ? // 未知方向,可能是設備(屏幕)斜置

UIDeviceOrientationPortrait,? ? ? ? ? ? ? ? // 設備(屏幕)直立

UIDeviceOrientationPortraitUpsideDown,? ? ? // 設備(屏幕)直立,上下顛倒

UIDeviceOrientationLandscapeLeft,? ? ? ? ? // 設備(屏幕)向左橫置

UIDeviceOrientationLandscapeRight,? ? ? ? ? // 設備(屏幕)向右橫置

UIDeviceOrientationFaceUp,? ? ? ? ? ? ? ? ? // 設備(屏幕)朝上平躺

UIDeviceOrientationFaceDown? ? ? ? ? ? ? ? // 設備(屏幕)朝下平躺

};

注意:UIDeviceOrientation參考home鍵方向,如:home方向在右,設備(屏幕)方向向左(UIDeviceOrientationLandscapeLeft)

1.2->讀取設備方向

UIDevice單例代表當前的設備。從這個單例中可以獲得設備信息,如:設備方向:Orientation。代碼如下? UIDeviceOrientation deviceOri = [UIDevice currentDevice].orientation;

1.3->監聽、處理和移除設備方向改變的通知

當設備方向變化的時候,會發出UIDeviceOrientationDidChangeNotification通知,注冊監聽該通知可以對不同的設備方向處理視圖展示。

//開啟和監聽 設備旋轉的通知(不開啟的話,設備方向一直是UIInterfaceOrientationUnknown)

if (![UIDevice currentDevice].generatesDeviceOrientationNotifications) {

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

}

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleDeviceOrientationChange:)

name:UIDeviceOrientationDidChangeNotification object:nil];

//設備方向改變的處理

- (void)handleDeviceOrientationChange:(NSNotification *)notification{

UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;

switch (ddeviceOrientation) {

case UIDeviceOrientationFaceUp:

NSLog(@"屏幕朝上平躺");

break;

case UIDeviceOrientationFaceDown:

NSLog(@"屏幕朝下平躺");

break;

case UIDeviceOrientationUnknown:

NSLog(@"未知方向");

break;

case UIDeviceOrientationLandscapeLeft:

NSLog(@"屏幕向左橫置");

break;

case UIDeviceOrientationLandscapeRight:

NSLog(@"屏幕向右橫置");

break;

case UIDeviceOrientationPortrait:

NSLog(@"屏幕直立");

break;

case UIDeviceOrientationPortraitUpsideDown:

NSLog(@"屏幕直立,上下顛倒");

break;

default:

NSLog(@"無法辨識");

break;

}

}

//最后在dealloc中移除通知 和結束設備旋轉的通知

- (void)dealloc{

[[NSNotificationCenter defaultCenter]removeObserver:self];

[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];}

注意:當手機鎖定豎屏后,name:UIDeviceOrientationDidChangeNotification通知就失效了

2->UIInterfaceOrientation:界面方向

界面方向是反映iOS中界面的方向,他和Home按鈕的方向是一致的。

2.1->iOS定義了下面五種界面方向

typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {

UIInterfaceOrientationUnknown? ? ? ? ? ? = UIDeviceOrientationUnknown,? ? ? //未知方向

UIInterfaceOrientationPortrait? ? ? ? ? = UIDeviceOrientationPortrait,? ? ? ? ? ? ? //界面直立

UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,? //界面直立,上下顛倒

UIInterfaceOrientationLandscapeLeft? ? ? = UIDeviceOrientationLandscapeRight,? //界面朝左

UIInterfaceOrientationLandscapeRight? ? = UIDeviceOrientationLandscapeLeft? ? //界面朝右

} __TVOS_PROHIBITED;

注意:從他們的定義可知:界面方向和設備方向是有對應關系的,如界面的豎直方向就是設備的豎直方向:UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown

2.2-> 讀取界面方向

UIInterfaceOrientation和狀態欄有關,通過UIApplication的單例調用statusBarOrientation來獲取

代碼如下:

UIInterfaceOrientation interfaceOri = [[UIApplication sharedApplication]statusBarOrientation];

2.3->監聽、處理和移除界面方向改變的通知

當界面方向變化時候,先后發出UIApplicationWillChangeStatusBarOrientationNotification和UIApplicationDidChangeStatusBarOrientationNotification通知;注冊監聽這兩個通知,可以針對不同的界面方向處理視圖展示。

//以監聽UIApplicationDidChangeStatusBarOrientationNotification通知為例

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleStatusBarOrientationChange:)

name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

//界面方向改變的處理

- (void)handleStatusBarOrientationChange: (NSNotification *)notification{

UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];

switch (interfaceOrientation) {

case UIInterfaceOrientationUnknown:

NSLog(@"未知方向");

break;

case UIInterfaceOrientationPortrait:

NSLog(@"界面直立");

break;

case UIInterfaceOrientationPortraitUpsideDown:

NSLog(@"界面直立,上下顛倒");

break;

case UIInterfaceOrientationLandscapeLeft:

NSLog(@"界面朝左");

break;

case UIInterfaceOrientationLandscapeRight:

NSLog(@"界面朝右");

break;

default:

break;

}

}

//最后在dealloc中移除通知

- (void)dealloc{

//...

[[NSNotificationCenter defaultCenter]removeObserver:self];

[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];

}

注意:手機鎖定豎屏后,UIApplicationWillChangeStatusBarOrientationNotification和UIApplicationDidChangeStatusBarOrientationNotification通知也失效了。

3->UIInterfaceOrientationMask

UIInterfaceOrientationMask是為了集成多種UIInterfaceOrientation而定義的類型,和ViewController相關,一共有7種

3.1->iOS中的UIInterfaceOrientationMask定義

typedef NS_OPTIONS(NSUInteger, UIInterfaceOrientationMask) {

UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),

UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),

UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),

UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),

UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),

UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),

UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),

} __TVOS_PROHIBITED;

3.2->UIInterfaceOrientationMask的使用

在ViewController可以重寫- (UIInterfaceOrientationMask)supportedInterfaceOrientations方法返回類型,來決定UIViewController可以支持哪些界面方向。

//支持界面直立

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

return UIInterfaceOrientationMaskPortrait;

}

總結:UIDeviceOrientation(設備方向)和UIInterfaceOrientation(屏幕方向)是兩個不同的概念。前者代表了設備的一種狀態,而后者是屏幕為了應對不同的設備狀態,做出的用戶界面上的響應。在iOS設備旋轉時,由UIKit接收到旋轉事件,然后通過AppDelegate通知當前程序的UIWindow對象,UIWindow對象通知它的rootViewController,如果該rootViewController支持旋轉后的屏幕方向,完成旋轉,否則不旋轉;彈出的ViewController也是如此處理。

4->視圖控制器中旋轉方向的設置

4.1->關于禁止橫屏的操作(不建議),比較常規的方法有兩種。方法1:在項目的General–>Deployment Info–>Device Orientation中,只勾選Portrait(豎屏)


方法2:Device Orientation默認設置,在Appdelegate中實現supportedInterfaceOrientationsForWindow:只返回UIInterfaceOrientationMaskPortraitt(豎屏)

-? (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window? {

return UIInterfaceOrientationMaskPortrait;

}

說明:極少的APP中所有界面都是豎屏的,因為總會有界面需要支持橫屏,如視頻播放頁。所以不建議設置禁止APP頁面橫屏。

5->? 何讓項目中的 視圖控制器中旋轉方向的設置

5.1->APP支持多個方向


說明:如此,APP支持橫屏和豎屏了,但是具體視圖控制器支持的頁面方向還需要進一步處理。由于不支持豎屏顛倒(Upside Down),即使設備上下顛倒,通過API也不會獲得設備、屏幕上下顛倒方向的。

5.2->支持ViewController屏幕方向設置

1)關鍵函數

視圖控制器支持的界面方向主要由以下三個函數控制

//是否自動旋轉,返回YES可以自動旋轉,返回NO禁止旋轉

- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;

//返回支持的方向

- (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;

//由模態推出的視圖控制器 優先支持的屏幕方向

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;

2) QSBaseViewController設置

//QSBaseViewController.h

@interface QSBaseController : UIViewController

@end

//QSBaseViewController.m

@implementation QSBaseController

//#pragma mark - 控制屏幕旋轉方法

//是否自動旋轉,返回YES可以自動旋轉,返回NO禁止旋轉

- (BOOL)shouldAutorotate{

return NO;

}

//返回支持的方向

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

return UIInterfaceOrientationMaskPortrait;

}

//由模態推出的視圖控制器 優先支持的屏幕方向

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

return UIInterfaceOrientationPortrait;

}

@end

說明1:QSBaseViewController默認不支持旋轉,只支持 界面豎直方向,項目中的Controller都繼承自QSBaseViewController,可以通過重寫這三個方法來讓Controller支持除豎屏之外的方向或旋轉。

3) 在QSNavigationController設置

目標:通過QSNavigationController來push視圖控制器時,把支持屏幕旋轉的設置交給最新push進來([self.viewControllers lastObject])的viewController來設置。

//QSNavigationController.h

@interface QSNavigationController : UINavigationController

@end

//QSNavigationController.m

@implementation QSNavigationController

#pragma mark - 控制屏幕旋轉方法

- (BOOL)shouldAutorotate{

return [[self.viewControllers lastObject]shouldAutorotate];

}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

return [[self.viewControllers lastObject]supportedInterfaceOrientations];

}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];

}

@end

4) 在QSTabBarController設置

目標:TabBarController通常作為整個程序的rootViewController,UITabBar上面顯示的每一個Tab都對應著一個ViewController;每點擊一個Tab,出現的ViewController(self.selectedViewController)對屏幕旋轉和支持方向的設置 交給其自身去控制。

//QSTabBarController.h

@interface QSTabBarController : UITabBarController

@end

//QSTabBarController.m

@implementation QSTabBarController

#pragma mark - 控制屏幕旋轉方法

- (BOOL)shouldAutorotate{

return [self.selectedViewController shouldAutorotate];

}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

return [self.selectedViewController supportedInterfaceOrientations];

}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

return [self.selectedViewController preferredInterfaceOrientationForPresentation];

}

@end

三、屏幕旋轉方向下的視圖處理

1、屏幕旋轉時,建議監聽UIApplicationDidChangeStatusBarOrientationNotification

原因1:supportedInterfaceOrientations方法中最終返回的是 多個界面方向。

原因2(最重要的原因):我們真正要處理的是頁面方向發生旋轉UI的變化。而在設備的物理方向發生旋轉的時候,如果此時當前控制器的頁面并沒有旋轉,我們這時改變UI布局,可能就發生問題了。

2、屏幕的寬高處理

1)在iOS 8之后,當屏幕旋轉的時候,[[UIScreen mainScreen] bounds]也發生了改變。如橫屏時候的屏幕寬度 其實是豎屏的時候屏幕的高度。

2)我們處理視圖布局時候,如果使用到屏幕的寬高,不要直接使用SCREEN_HEIGHT和SCREEN_WIDTH,而使用SCREEN_MIN和SCREEN_MAX

#define SCREEN_HEIGHT CGRectGetHeight([[UIScreen mainScreen] bounds])

#define SCREEN_WIDTH? CGRectGetWidth([[UIScreen mainScreen] bounds])

#define SCREEN_MIN MIN(SCREEN_HEIGHT,SCREEN_WIDTH)

#define SCREEN_MAX MAX(SCREEN_HEIGHT,SCREEN_WIDTH)

說明:豎屏時候,寬是SCREEN_MIN,高是SCREEN_MAX;橫屏時候,寬是SCREEN_MAX,高是SCREEN_MIN。

3、屏幕旋轉下處理Demo

//監聽UIApplicationDidChangeStatusBarOrientationNotification的處理

- (void)handleStatusBarOrientationChange: (NSNotification *)notification{

UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];

BOOL isLandscape = NO;

switch (interfaceOrientation) {

case UIInterfaceOrientationUnknown:

NSLog(@"未知方向");

break;

case UIInterfaceOrientationPortrait:

case UIInterfaceOrientationPortraitUpsideDown:

isLandscape = NO;

break;

case UIInterfaceOrientationLandscapeLeft:

case UIInterfaceOrientationLandscapeRight:

isLandscape = YES;

break;

default:

break;

}

if (isLandscape) {

self.tableView.frame = CGRectMake(0, 0, SCREEN_MAX, SCREEN_MIN - 44);

}else{

self.tableView.frame = CGRectMake(0, 0, SCREEN_MIN, SCREEN_MAX - 64);

}

[self.tableView reloadData];

}

說明:當然也可以選擇使用Masonry這樣優秀的AutoLayout布局第三方庫來處理,storyBoard來布局次之。

5、屏幕旋轉處理的建議

1)旋轉前后,view當前顯示的位置盡量不變

2)旋轉過程中,暫時界面操作的響應

3)視圖中有tableview的話,旋轉后,強制 [tableview reloadData],保證在方向變化以后,新的row能夠充滿全屏。

四、強制橫屏

APP中某些頁面,如視頻播放頁,一出現就要求橫屏。這些橫屏頁面或模態彈出、或push進來。

1、模態彈出ViewController情況下 強制橫屏的設置

//QSShow3Controller.m

- (BOOL)shouldAutorotate{

return NO;

}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

return UIInterfaceOrientationMaskLandscapeRight;

}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{

return UIInterfaceOrientationLandscapeRight;

}

//模態彈出

QSShow3Controller *vc = [[QSShow3Controller alloc]init];

[self presentViewController:vc animated:YES completion:nil];

說明:這種情況比較簡單處理。

2、push推入ViewController情況下 強制橫屏的設置

//QSShow4Controller.m

-(void)viewWillAppear:(BOOL)animated{

[super viewWillAppear:animated];

[self setInterfaceOrientation:UIInterfaceOrientationLandscapeRight];

}

//強制轉屏(這個方法最好放在BaseVController中)

- (void)setInterfaceOrientation:(UIInterfaceOrientation)orientation{

if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {

SEL selector? = NSSelectorFromString(@"setOrientation:");

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];

[invocation setSelector:selector];

[invocation setTarget:[UIDevice currentDevice]];

// 從2開始是因為前兩個參數已經被selector和target占用

[invocation setArgument:&orientation atIndex:2];

[invocation invoke];

}

}

//必須返回YES

- (BOOL)shouldAutorotate{

return YES;

}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations{

return UIInterfaceOrientationMaskLandscapeRight;

}

//Push推入

QSShow4Controller *vc = [[QSShow4Controller alloc]init];

[self.navigationController pushViewController:vc animated:YES];

說明:蘋果不允許直接調用setOrientation方法,否則有被拒的風險;使用NSInvocation對象給[UIDevice currentDevice]發消息,強制改變設備方向,使其頁面方向對應改變,這是蘋果允許的。

五、其他

1、 APP啟動時,手機橫屏下,首頁UI(該頁面只支持豎屏)出錯(add by 2017/6/20)

//設置設置狀態欄豎屏

[[UIApplication sharedApplication]setStatusBarOrientation:UIInterfaceOrientationPortrait];

*/

如果要在每個控制器都寫這兩個方法,麻煩程度不敢想象。所以我們可以借助分類來實現,這樣既簡單又優雅,而且維護起來集中干凈

------------------------------

#import@interface UIViewController (Landscape)

@property(nonatomic) BOOL bl_shouldAutoLandscape;//是否需要橫屏,默認NO,即當前控制器不支持橫屏

@end

-------------------------------------

#import "UIViewController+Landscape.h"

#import <objc/runtime.h>

@implementation UIViewController (Landscape)

+ (void)load{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

id obj = [[self alloc]init];

[obj swizzleMethod:@selector(shouldAutorotate) withMethod:@selector(bl_shouldAutorotate) error:nil];

[obj swizzleMethod:@selector(supportedInterfaceOrientations) withMethod:@selector(bl_supportedInterfaceOrientation) error:nil];

});

}

- (void)swizzleMethod:(SEL)currentMethod withMethod:(SEL)fromMethod error:(NSError* )error{

Class class = [self class];

Method originalMethod = class_getInstanceMethod(class, currentMethod);//Method是運行時庫的類

Method swizzledMethod = class_getInstanceMethod(class, fromMethod);

BOOL didAddMethod = class_addMethod(class, currentMethod, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));

if (didAddMethod) {

class_replaceMethod(class, fromMethod, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));

}else{

method_exchangeImplementations(originalMethod, swizzledMethod);

}

}

- (BOOL)bl_shouldAutorotate{//是否支持旋轉

if ([self isKindOfClass:NSClassFromString(@"RootViewController")]) {//根視圖

return self.childViewControllers.firstObject.shouldAutorotate;

}

if ([self isKindOfClass:NSClassFromString(@"ViewController")]) {//某個控制器

return self.childViewControllers.firstObject.shouldAutorotate;

}

if ([self isKindOfClass:NSClassFromString(@"UITabBarController")]) {//UITabBarController控制器

return ((UITabBarController*) self).selectedViewController.shouldAutorotate;

}

if ([self isKindOfClass:NSClassFromString(@"UINavigationController")]) {//UINavigationController控制器

return ((UINavigationController*) self).childViewControllers.lastObject.shouldAutorotate;

}

if ([self isKindOfClass:NSClassFromString(@"ListViewController")]) {//某個需要旋轉的視圖控制器

return YES;

}

if (self.bl_shouldAutoLandscape) {

return YES;

}

return NO;

}

- (UIInterfaceOrientationMask)bl_supportedInterfaceOrientation{//支持旋轉的方向

if ([self isKindOfClass:NSClassFromString(@"RootViewController")]) {//根視圖

return [self.childViewControllers.firstObject supportedInterfaceOrientations];

}

if ([self isKindOfClass:NSClassFromString(@"ViewController")]) {//某個控制器

return [self.childViewControllers.firstObject supportedInterfaceOrientations];

}

if ([self isKindOfClass:NSClassFromString(@"UITabBarController")]) {//UITabBarController控制器

return [((UITabBarController*) self).selectedViewController supportedInterfaceOrientations];

}

if ([self isKindOfClass:NSClassFromString(@"UINavigationController")]) {//UINavigationController控制器

return [((UINavigationController*) self).childViewControllers.lastObject supportedInterfaceOrientations];

}

if ([self isKindOfClass:NSClassFromString(@"ListViewController")]) {//某個需要旋轉的視圖控制器

return? UIInterfaceOrientationMaskAllButUpsideDown;

}

if (self.bl_shouldAutoLandscape) {

return? UIInterfaceOrientationMaskAllButUpsideDown;

}

return? UIInterfaceOrientationMaskPortrait;

}

- (void)setBl_shouldAutoLandscape:(BOOL)bl_shouldAutoLandscape{

objc_setAssociatedObject(self, @selector(bl_shouldAutoLandscape), @(bl_shouldAutoLandscape), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (BOOL)bl_shouldAutoLandscape{

return [objc_getAssociatedObject(self, _cmd) boolValue];

}

--------------------------------------

七.實現某些網頁橫屏

一種方式是和 h5 約定一個事件,如果有視頻就告訴原生 APP 做一個標記,將 bl_shouldAutoLandscape 置為 YES。

但是我這里提供一種更加簡便優雅的方式,我們的 UIWebView 是可以通過 -stringByEvaluatingJavaScriptFromString: 方法和我們交互的,所以我們可以嘗試下面的方法:

#pragma mark - UIWebViewDelegate- (void)webViewDidFinishLoad:

(UIWebView *)webView{? ? NSString *result = [webView

stringByEvaluatingJavaScriptFromString:@"if(document.getElementsByTagName

('video').length>0)document.getElementsByTagName('video').length;"];

if (result.length && result.integerValue != 0)

{? ? ? ? self.bl_shouldAutoLandscape = YES;? ? }}


----------------------------------------------

添加UIViewController視圖控制器的分類之后,在需要的地方,添加代碼:self.bl_shouldAutoLandscape = YES;即可。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容