iOS自定義轉(zhuǎn)場動畫-1

像我們平常用的最多的就是presentViewController:animated:completion:和對應的dismissViewControllerAnimated:completion:來實現(xiàn)展示視圖和隱藏視圖。最近看了官方的Demo,對于我這種小菜鳥著實下了一番功夫才搞明白邮绿。詳細代碼可以在這里下載贪绘,如果覺得有用,可以隨手star一下主籍。

動畫效果 只實現(xiàn)了其中的一部分

Untitled.gif

第一個效果(Cross Dissolve)

. 1 首先當前的控制器需要遵守UIViewControllerTransitioningDelegate點擊command進去可以看到有5個代理方法衫冻,由于當前的動畫沒有涉及到用戶的交互情況饥瓷,所以只實現(xiàn)了前兩個方法槐臀,它返回的是一個遵守了UIViewControllerAnimatedTransitioningid對象蜡峰,UIViewControllerAnimatedTransitioning它是用來控制動畫的持續(xù)時間和展示邏輯。

#import <UIKit/UIKit.h>
@interface CrossDissolveAnimator : NSObject<UIViewControllerAnimatedTransitioning>
@end
#import "CrossDissolveAnimator.h"
@implementation CrossDissolveAnimator
//動畫持續(xù)的時長
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{
    return 0.35;
}
//動畫相關(guān)的參數(shù)
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    //動畫相關(guān)聯(lián)的兩個控制器
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    //containerView:本人理解是如果沒有動畫狼牺,則為fromView,如果在動畫的過程中羡儿,則為toView
    UIView *containerView = transitionContext.containerView;
    UIView *fromView;
    UIView *toView;
    
    //iOS8引入了viewForKey方法,系統(tǒng)會優(yōu)先訪問這個方法是钥,另外viewForKey這個方法有可能會返回nil,盡量不直接訪問controller的view屬性掠归,就比如第三個demo從底部彈出的動畫,給presentedViewController的view添加了圓角陰影等效果悄泥,viewForKey訪問到的是所有的view 而presentedViewController的view只能訪問到其中的一個子視圖
    if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {
        fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
        toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    }else{
        fromView = fromViewController.view;
        toView = toViewController.view;
    }
    
    fromView.frame = [transitionContext initialFrameForViewController:fromViewController];
    toView.frame = [transitionContext finalFrameForViewController:toViewController];
    
    fromView.alpha = 1.0f;
    toView.alpha = 0.0f;
    
    //在present和虏冻,dismiss時,必須將toview添加到視圖層次中
    [containerView addSubview:toView];
    NSTimeInterval transitionDurating = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:transitionDurating animations:^{
        fromView.alpha = 0.0f;
        toView.alpha = 1.0f;
    } completion:^(BOOL finished) {
        BOOL wasCancelled = [transitionContext transitionWasCancelled];
        [transitionContext completeTransition:!wasCancelled];
    }];
}
@end

以上為核心的代碼弹囚,這里借用下別人的圖片來注明一下用到的fromViewtoView


另外需要注意厨相,modalPresentationStyle需要是UIModalPresentationFullScreen,fullCustom的本質(zhì)區(qū)別是full會移除fromView,但是Custom卻不會。

第二個效果(Swipe)

首先先分析鸥鹉,它既可以點擊自定義跳轉(zhuǎn)蛮穿,其次又可以添加手勢來滑動,所以不僅要實現(xiàn)UIViewControllerTransitioningDelegate中的方法而且我們還要計算在手勢拖動中百分比的控制毁渗,官方已經(jīng)封裝好了我們只需要實現(xiàn)UIPercentDrivenInteractiveTransition協(xié)議就好了践磅。并且當前的轉(zhuǎn)場動畫是交互式的動畫,判斷的依據(jù)就是可以手勢滑動灸异。
.1 自定義一個類遵守UIViewControllerTransitioningDelegate通過動畫我們可以看出府适,當present的時候是從屏幕的右邊開始,dismiss從左邊開始消失肺樟,所以我們要計算兩個toView的frame值
首先實現(xiàn)點擊Button來轉(zhuǎn)場

#import <UIKit/UIKit.h>
@interface SwipeTransitionAnimatar : NSObject<UIViewControllerAnimatedTransitioning>
@property(nonatomic,assign) UIRectEdge edge;//用來判斷是左滑還是右滑
- (instancetype)initWithTargetEdge:(UIRectEdge)dege;
@end
#import "SwipeTransitionAnimatar.h"

@implementation SwipeTransitionAnimatar
- (instancetype)initWithTargetEdge:(UIRectEdge)dege{
    if (self = [super init]) {
        _edge = dege;
    }
    return self;
}
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;
{
    return 0.35f;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *containerView = transitionContext.containerView;
    UIView *fromView;
    UIView *toView;
    if ([transitionContext respondsToSelector:@selector(viewForKey:)]) {
        fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
        toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    }else{
        fromView = fromViewController.view;
        toView = toViewController.view;
    }
    // isPresenting用于判斷當前是present還是dismiss
    BOOL isPresenting = (toViewController.presentingViewController == fromViewController);
    
    CGRect fromFrame = [transitionContext initialFrameForViewController:fromViewController];
    CGRect toFrame = [transitionContext finalFrameForViewController:toViewController];
    
   __block  CGVector offset;//用于計算toView的位置
    //定義一個二維矢量運動的方向檐春,重力方向默認的是(0.f,1.f),dx為-1.0f時向左運動,dy為-1.0時向上運動
     if (self.edge == UIRectEdgeLeft){
        offset = CGVectorMake(1.f, 0.f);//從左邊屏幕開始滑動表示dismiss時
    }else if (self.edge == UIRectEdgeRight){
        offset = CGVectorMake(-1.f, 0.f);//從右邊開始滑動表示present時
    }else{
        NSAssert(NO, @"targetEdge must be one of UIRectEdgeLeft, or UIRectEdgeRight.");
    }
    
    //根據(jù)當前是present還是dismiss來計算好toView的初始位置以及結(jié)束位置
    if (isPresenting) {
        fromView.frame = fromFrame;
        toView.frame = CGRectOffset(toFrame, toFrame.size.width*offset.dx*-1, toFrame.size.height*offset.dy*-1);
    }else{
        fromView.frame = fromFrame;
        toView.frame = toFrame;
    }

    if (isPresenting) {
        [containerView addSubview:toView];
    }else{
        [containerView insertSubview:toView belowSubview:fromView];
    }
    NSTimeInterval transitionDurating = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:transitionDurating animations:^{
        if (isPresenting) {
            toView.frame = toFrame;
        }else{
            fromView.frame = CGRectOffset(toFrame, toFrame.size.width*offset.dx, toFrame.size.height*offset.dy);
        }
    } completion:^(BOOL finished) {
       BOOL wasCancelled = [transitionContext transitionWasCancelled];
        if (wasCancelled)
            [toView removeFromSuperview];
        [transitionContext completeTransition:!wasCancelled];
    }];
}
@end

.2 自定義動畫百分比控制器來實現(xiàn)手勢滑動的時候所占的百分比

#import "SwipePercentInteractionController.h"

@interface SwipePercentInteractionController ()
@property(nonatomic,strong)id<UIViewControllerContextTransitioning> transitionContext;//用來存儲實時的transitionContext
@property(nonatomic,strong)UIScreenEdgePanGestureRecognizer *pan;
@property(nonatomic,assign) UIRectEdge edge;
@end

@implementation SwipePercentInteractionController
- (instancetype)initWithGestureRecognizer:(UIScreenEdgePanGestureRecognizer *)pan edgeForDragging:(UIRectEdge)edge{
    if (self = [super init]) {
        _pan = pan;
        _edge = edge;
        [_pan addTarget:self action:@selector(pan:)];
    }
    return self;
}
- (instancetype)init{
    @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Use -initWithGestureRecognizer:edgeForDragging:" userInfo:nil];
}
- (void)dealloc{
    [self.pan removeTarget:self action:@selector(pan:)];
}
//不應該緩存transitionContext么伯,而是動態(tài)的獲取疟暖,這樣保證拿到的始終是最新的,最正確的消息
-(void)startInteractiveTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    self.transitionContext = transitionContext;
    [super startInteractiveTransition:transitionContext];
}
//根據(jù)當前手勢觸摸的點從而計算出偏移的百分比
- (CGFloat)percentForGuesture:(UIScreenEdgePanGestureRecognizer *)pan{
    UIView *transitionContainerView = self.transitionContext.containerView;
    CGPoint location = [pan locationInView:transitionContainerView];
    CGFloat width = CGRectGetWidth(transitionContainerView.bounds);
    if (self.edge == UIRectEdgeLeft) {
        return location.x/width;
    }else if (self.edge == UIRectEdgeRight){
        return (width - location.x)/width;
    }else
        return 0.f;
}
//手勢滑動觸發(fā)方法
- (void)pan:(UIScreenEdgePanGestureRecognizer *)pan{
    switch (pan.state) {
        case UIGestureRecognizerStateBegan:
            break;
        case UIGestureRecognizerStateChanged://手勢滑動,更新百分比
            [self updateInteractiveTransition:[self percentForGuesture:pan]];
            break;
        case UIGestureRecognizerStateEnded: // 滑動結(jié)束俐巴,判斷是否超過一半朋贬,如果是則完成剩下的動畫,否則取消動畫
            if ([self percentForGuesture:pan] >= 0.5f) {
                [self finishInteractiveTransition];
            }else{
                [self cancelInteractiveTransition];
            }
            break;
            
        default:
            [self cancelInteractiveTransition];
            break;
    }
}
@end

.3 實現(xiàn)UIViewControllerTransitioningDelegate代理方法

@implementation SwipeTransitioningDelegate

//   === 點擊Button的時候走下面這兩個方法  ===
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
    return [[SwipeTransitionAnimatar alloc]initWithTargetEdge:self.edge];
}

- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
    return [[SwipeTransitionAnimatar alloc]initWithTargetEdge:self.edge];
}

//=== 用手勢滑動的時候走這兩個方法 ====
- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator{
    if (self.pan) {
        return [[SwipePercentInteractionController alloc]initWithGestureRecognizer:self.pan edgeForDragging:self.edge];
    }
    else
        return nil;
}

- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator{
    if (self.pan) {
        return [[SwipePercentInteractionController alloc]initWithGestureRecognizer:self.pan edgeForDragging:self.edge];
    }
    else
        return nil;
}

@end

第三個效果(Custom Presentation)

分析動畫我們可以知道窜骄,presented出來的view自定義的有陰影,有圓角等而且frame并不是整個屏幕摆屯,這種比較徹底的自定義的presentedView我們可以使用轉(zhuǎn)場協(xié)調(diào)器UIPresentationController來實現(xiàn),它在轉(zhuǎn)場動畫的執(zhí)行過程中一直存在邻遏。UIPresentationController具有以下的功能:
1.設置presentedViewController的視圖大小
2.添加自定義視圖來改變presentedView的外觀
3.為任何自定義的視圖提供轉(zhuǎn)場動畫效果
4.根據(jù)size class進行響應式布局
由于```UIPresentationController``是一個基類,所以我們需要自定義實現(xiàn)一個類來集成它虐骑。該類主要的四個方法,顧名思義准验,就是在轉(zhuǎn)場動畫將要開始(在這里定義視圖層級結(jié)構(gòu)和frame),開始廷没,將要結(jié)束,結(jié)束時的操作糊饱。

- (void)presentationTransitionWillBegin;
- (void)presentationTransitionDidEnd:(BOOL)completed;
- (void)dismissalTransitionWillBegin;
- (void)dismissalTransitionDidEnd:(BOOL)completed;
#import "CustomPresentatitionTransitioning.h"

@interface CustomPresentatitionTransitioning ()<UIViewControllerAnimatedTransitioning>
@property(nonatomic,strong)UIView *dimmingView;//后面的視圖遮罩
@property(nonatomic,strong)UIView *presentationWrappingView;//添加動畫效果的view
@end

@implementation CustomPresentatitionTransitioning
//  =============  UIPresentationController初始化 方法 ==================
- (instancetype)initWithPresentedViewController:(UIViewController *)presentedViewController presentingViewController:(UIViewController *)presentingViewController{
    if (self = [super initWithPresentedViewController:presentedViewController presentingViewController:presentingViewController]) {
        //Custom不會移除presentingView
        presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
    }
    return self;
}
- (UIView *)presentedView{
    return self.presentationWrappingView;
}
//轉(zhuǎn)場將要開始的時候,布局視圖的層級結(jié)構(gòu)和frame
- (void)presentationTransitionWillBegin{
    //可以更改自身的視圖層級颠黎,添加額外的效果(陰影另锋,圓角)
    UIView *presentedViewControllerView = [super presentedView];
    presentedViewControllerView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
  
    /*運行的效果是由三個View疊加在一起形成的效果層級關(guān)系是
     presentationWapperView(負責陰影)
            presentationRoundedCornerView(負責圓角)
                   presentedViewControllerWrapperView
                         presentedViewControllerView
     
     */
    UIView *presentationWapperView = [[UIView alloc]initWithFrame:self.frameOfPresentedViewInContainerView];
    presentationWapperView.layer.shadowOpacity = 0.44f;//陰影不透明
    presentationWapperView.layer.shadowRadius = 13.f;
    presentationWapperView.layer.shadowOffset = CGSizeMake(0, -6.f);
    self.presentationWrappingView = presentationWapperView;
    
    UIView *presentationRoundedCornerView = [[UIView alloc]initWithFrame:UIEdgeInsetsInsetRect(presentationWapperView.bounds, UIEdgeInsetsMake(0, 0, -16, 0))];
    presentationRoundedCornerView.autoresizingMask =  UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
    presentationRoundedCornerView.layer.cornerRadius = 16;
    presentationRoundedCornerView.layer.masksToBounds = YES;
    
    UIView *presentedViewControllerWrapperView = [[UIView alloc]initWithFrame:UIEdgeInsetsInsetRect(presentationRoundedCornerView.bounds, UIEdgeInsetsMake(0, 0, 16, 0))];
    presentedViewControllerWrapperView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
    presentedViewControllerView.frame = presentedViewControllerWrapperView.bounds;
    //層級關(guān)系
    [presentationWapperView addSubview:presentationRoundedCornerView];
    [presentationRoundedCornerView addSubview:presentedViewControllerWrapperView];
    [presentedViewControllerWrapperView addSubview:presentedViewControllerView];
    
    //添加一個dimmingview(昏暗)在presentationWrapperView的后面,然后再添加self.presentedView 這樣的話dimmingview都出現(xiàn)在presentedView的后面
    UIView *dimmingView = [[UIView alloc]initWithFrame:self.containerView.bounds];
    dimmingView.backgroundColor = [UIColor blackColor];
    dimmingView.opaque = NO;//透明
    dimmingView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [dimmingView addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)]];
    self.dimmingView = dimmingView;
    [self.containerView addSubview:dimmingView];
    
    
    id <UIViewControllerTransitionCoordinator> transitionCoordinator = self.presentingViewController.transitionCoordinator;
    self.dimmingView.alpha = 0.f;
    [transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        self.dimmingView.alpha = 0.5;
    } completion:nil];
}
//轉(zhuǎn)場完成時清除多余的視圖
- (void)presentationTransitionDidEnd:(BOOL)completed{
    //如果present沒有完成狭归,把dimmingView和wrappingView都清空夭坪,這些臨時視圖用不到了
    if (completed == NO) {
        self.presentationWrappingView = nil;
        self.dimmingView = nil;
    }
}
- (void)dismissalTransitionWillBegin{
    id <UIViewControllerTransitionCoordinator> transitionCoordinator = self.presentingViewController.transitionCoordinator;
    [transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
        self.dimmingView.alpha = 0.f;
    } completion:nil];
}
- (void)dismissalTransitionDidEnd:(BOOL)completed{
    if (completed) {
        self.presentationWrappingView = nil;
        self.dimmingView = nil;
    }
}
// =============  如果當前DidChange的視圖是presentedViewController,UIContentContainer重新布局子視圖 ==========
- (void)preferredContentSizeDidChangeForChildContentContainer:(id<UIContentContainer>)container{
    [super preferredContentSizeDidChangeForChildContentContainer:container];
    if (container == self.presentedViewController) {
        [self.containerView setNeedsLayout];
    }
}
- (CGSize)sizeForChildContentContainer:(id<UIContentContainer>)container withParentContainerSize:(CGSize)parentSize{
    if (container == self.presentedViewController) {
        return ((UIViewController *)container).preferredContentSize;
    }else
        return [super sizeForChildContentContainer:container withParentContainerSize:parentSize];
    
}
//重寫系統(tǒng)方法計算presentedViewController的大小
- (CGRect)frameOfPresentedViewInContainerView{
    CGRect containerViewBounds = self.containerView.bounds;
    CGSize presentedViewContentSize = [self sizeForChildContentContainer:self.presentedViewController withParentContainerSize:containerViewBounds.size];
    
    CGRect presentedViewControllerFrame = CGRectMake(containerViewBounds.origin.x, CGRectGetMaxY(containerViewBounds) - presentedViewContentSize.height, presentedViewContentSize.width, presentedViewContentSize.height);
    return presentedViewControllerFrame;
}

- (void)containerViewWillLayoutSubviews{
    [super containerViewWillLayoutSubviews];
    self.dimmingView.frame = self.containerView.bounds;
    self.presentationWrappingView.frame = self.frameOfPresentedViewInContainerView;
}

- (IBAction)tap:(UITapGestureRecognizer *)tap{
    
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

@end

總結(jié):

其實實現(xiàn)自定義轉(zhuǎn)場動畫無非就是以下幾步:
1.設置將要跳轉(zhuǎn)的目的控制器presentedViewControllertransitationingDelegate
2.充當代理的對象可以是 self(比較簡單的動畫)也可以是自定義的一個實現(xiàn)了UIViewControllerTransitioningDelegate的類。
3.在2的該類中實現(xiàn)指定的代理方法返回對應的Animater,Animater是實現(xiàn)了UIViewControllerAnimatedTransitioning的對象过椎,轉(zhuǎn)場動畫的所有的核心代碼都是在該Animater中實現(xiàn)

自定義動畫還有很多需要學習研究的地方室梅,遠遠不止這些,以上僅為自己總結(jié)的一點點心得疚宇。還有幾個轉(zhuǎn)場動畫有時間繼續(xù)更新亡鼠!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市敷待,隨后出現(xiàn)的幾起案子间涵,更是在濱河造成了極大的恐慌,老刑警劉巖讼撒,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浑厚,死亡現(xiàn)場離奇詭異,居然都是意外死亡根盒,警方通過查閱死者的電腦和手機钳幅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炎滞,“玉大人敢艰,你說我怎么就攤上這事〔崛” “怎么了钠导?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵震嫉,是天一觀的道長。 經(jīng)常有香客問我牡属,道長票堵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任逮栅,我火速辦了婚禮悴势,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘措伐。我一直安慰自己特纤,他們只是感情好,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布侥加。 她就那樣靜靜地躺著捧存,像睡著了一般。 火紅的嫁衣襯著肌膚如雪担败。 梳的紋絲不亂的頭發(fā)上昔穴,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音提前,去河邊找鬼傻咖。 笑死,一個胖子當著我的面吹牛岖研,可吹牛的內(nèi)容都是我干的卿操。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼孙援,長吁一口氣:“原來是場噩夢啊……” “哼害淤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拓售,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤窥摄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后础淤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體崭放,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年鸽凶,在試婚紗的時候發(fā)現(xiàn)自己被綠了币砂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡玻侥,死狀恐怖决摧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤掌桩,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布边锁,位于F島的核電站,受9級特大地震影響波岛,放射性物質(zhì)發(fā)生泄漏茅坛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一则拷、第九天 我趴在偏房一處隱蔽的房頂上張望灰蛙。 院中可真熱鬧,春花似錦隔躲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至叛薯,卻和暖如春浑吟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耗溜。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工组力, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抖拴。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓燎字,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阿宅。 傳聞我的和親對象是個殘疾皇子候衍,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

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