使用 CGPDFDocument儿惫、CATiledLayer 和 UIPageViewController 做簡(jiǎn)單的 PDF 閱讀器(二)

0

上文已經(jīng)講述了如何使用 CGPDFDocument 和 CATiledLayer 繪制 PDF 文件,現(xiàn)在我們添加手勢(shì)來(lái)縮放 PDF, 然后再使用 UIPageViewController 制作一個(gè)翻頁(yè)效果.

單頁(yè) PDF 的縮放

self.pdfContentView = [[UIView alloc]init];
[self.pdfContentContainerView addSubview:self.pdfContentView];
self.pdfContentLayer = [[PDFContentTiledLayer alloc]init];
self.pdfContentLayer.delegate = self;
[self.pdfContentView.layer addSublayer:self.pdfContentLayer];

我們將單頁(yè) PDF 顯示在 PDFContentTiledLayer 然后將 PDFContentTiledLayer 放在 pdfContentView 內(nèi)顯示出來(lái).
因?yàn)槲覀兊?pdfContentView 是使用 autolayout 進(jìn)行布局的,并且支持橫屏和豎屏顯示,所以在設(shè)備方向發(fā)生變化時(shí), pdfContentView 的會(huì)觸發(fā) layout, 我們要在 layout 之后,重置 PDF 縮放狀態(tài).

- (void)viewDidLayoutSubviews{
    [self adjustPdfContentFrame];
    [self centerScrollViewContent];
    [self drawThumb];
    [super viewDidLayoutSubviews];
}

重新計(jì)算 PDF 頁(yè)面的縮放狀態(tài)

//調(diào)整 pdfContentView 將 PDF 縮放到 1x
- (void)adjustPdfContentFrame{
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    CGRect maxContentRect = self.pdfContentContainerView.bounds;
    if (_pdfPage != nil) {
        CGRect pdfPageOriginalPageRect = CGPDFPageGetBoxRect(_pdfPage, PDFContentDefaultPDFBox);
        CGSize adjustPageSize = maxContentRect.size;
        double contentRate = maxContentRect.size.width/(maxContentRect.size.height > 0?maxContentRect.size.height:screenSize.height);
        double pdfOriginalRate = pdfPageOriginalPageRect.size.width/(pdfPageOriginalPageRect.size.height > 0? pdfPageOriginalPageRect.size.height:screenSize.height);
        //判斷寬高比
        //pdf 原始寬度大于顯示區(qū)域?qū)挾?需要將寬度縮放到顯示區(qū)域?qū)挾?并且相應(yīng)的縮放高度
        if (pdfOriginalRate > contentRate) {
            double scaleRate = pdfPageOriginalPageRect.size.width/maxContentRect.size.width;
            double scaleWidth = maxContentRect.size.width;
            double scaleHeight = pdfPageOriginalPageRect.size.height/(scaleRate > 0?scaleRate:1);
            adjustPageSize = CGSizeMake(scaleWidth, scaleHeight);
        }else{
            double scaleRate = pdfPageOriginalPageRect.size.height/maxContentRect.size.height;
            double scaleWidth = pdfPageOriginalPageRect.size.width/(scaleRate > 0?scaleRate:1);
            double scaleHeight = maxContentRect.size.height;
            adjustPageSize = CGSizeMake(scaleWidth, scaleHeight);
        }
        
        self.pdfContentView.frame = CGRectMake(0, 0, adjustPageSize.width, adjustPageSize.height);
        self.pdfContentContainerView.contentSize = self.pdfContentView.bounds.size;
        if (!CGRectEqualToRect(self.pdfContentLayer.bounds, self.pdfContentView.layer.bounds)) {
            self.pdfContentLayer.frame = self.pdfContentView.layer.bounds;
            //重新計(jì)算之后, CATiledLayer 需要重新繪圖,這里重新生成縮略圖避免閃屏
            [self drawThumb];
            [self.pdfContentLayer setNeedsDisplay];
        }
    }else{
        self.pdfContentView.frame = CGRectZero;
        self.pdfContentLayer.frame = self.pdfContentView.layer.bounds;
        self.pdfContentContainerView.contentSize = self.pdfContentView.bounds.size;
    }
}
//保證 pdf 在 ScrollView 中間位置
- (void)centerScrollViewContent
{
    CGFloat iw = 0.0f; CGFloat ih = 0.0f; // Content width and height insets
    
    CGSize boundsSize = self.pdfContentContainerView.bounds.size;
    CGSize contentSize = self.pdfContentContainerView.contentSize; // Sizes
    
    if (contentSize.width < boundsSize.width) iw = ((boundsSize.width - contentSize.width) * 0.5f);
    
    if (contentSize.height < boundsSize.height) ih = ((boundsSize.height - contentSize.height) * 0.5f);
    
    UIEdgeInsets insets = UIEdgeInsetsMake(ih, iw, ih, iw); // Create (possibly updated) content insets
    
    if (UIEdgeInsetsEqualToEdgeInsets(self.pdfContentContainerView.contentInset, insets) == false){
        self.pdfContentContainerView.contentInset = insets;
    }
}

將 PDF 頁(yè)重置后,就開(kāi)始進(jìn)行縮放了.
為了將左滑右滑翻頁(yè)結(jié)合起來(lái),我們不把手勢(shì)放在 PDFContentViewController 類(lèi)里面,而是把這些手勢(shì)定義在 PDFViewController 里面.
這個(gè) PDFViewController 的功能主要有如下幾條:

  1. 讀取 PDF 文件
  2. 從 PDF 文件中讀取一個(gè)頁(yè)面
  3. 添加滑動(dòng)手勢(shì),控制翻頁(yè).添加雙擊手勢(shì)進(jìn)行放大
  4. 實(shí)現(xiàn)翻頁(yè)效果.
    總之這個(gè) PDFViewController 作為 PDFContentViewController 的容器,完成 PDF 顯示之外的控制工作.

當(dāng)然, PDFContentViewController 本身要有縮放功能,并把這些功能的接口暴露出來(lái)給 PDFViewController 使用.
由于 PDFContentViewController 和是使用 UIScrollView 來(lái)進(jìn)行縮放的,這里和 PDFViewController 的翻頁(yè)功能產(chǎn)生了一定的沖突,這里先不提,我們先把縮放效果做完.

翻頁(yè)很簡(jiǎn)單,只要實(shí)現(xiàn) UIScrollview 的 delegate 就可以了,其實(shí),不過(guò)不需要兼顧翻頁(yè)效果,也不用處理 UIScrollview 的 delegate.

#pragma UIScrollViewDelegate

- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
   //NSLog(@"%@",scrollView);
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
   NSLog(@"scrollViewDidEndZooming %@   %@   %lf",scrollView,view,scale);
   [self centerScrollViewContent];
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
   return self.pdfContentView;
}

這里只有一個(gè)要注意的就是,每次縮放后,把 PDF 頁(yè)面中心放到屏幕中間,否則用起來(lái)會(huì)怪怪的.

    [self centerScrollViewContent];

縮放就完成了.

翻頁(yè)效果,以及處理翻頁(yè)動(dòng)畫(huà)與 UIScrollView 縮放之間產(chǎn)生的沖突

翻頁(yè)效果的制作

iOS 上實(shí)現(xiàn)翻頁(yè)效果,可以使用系統(tǒng)帶的 UIPageViewController剿涮,方便快捷奢赂,效果非常好偏竟。我的直接領(lǐng)導(dǎo),公司移動(dòng)端的負(fù)責(zé)人民轴,現(xiàn)在負(fù)責(zé) Android 客戶端開(kāi)發(fā)攻柠,為了實(shí)現(xiàn)相同的效果,花了好幾天時(shí)間用 openGL 畫(huà)了一個(gè)后裸。哎瑰钮,確實(shí)比我牛好多。
使用 UIPageViewController 需要在它的代理方法(UIPageViewControllerDataSource UIPageViewControllerDelegate)中提供一系列 UIViewController 作為 childViewController 供顯示內(nèi)容用轻抱。

  1. 直接翻頁(yè)
//直接切換頁(yè)面
- (void)switchToPage:(NSInteger)pageNumber animated:(BOOL)animated{
    self.pdfCurrentViewController = [self showPage:pageNumber];
    if (self.pdfCurrentViewController != nil) {
        _currentPageNum = pageNumber;
        [self.pdfReaderViewController setViewControllers:@[self.pdfCurrentViewController] direction:UIPageViewControllerNavigationDirectionForward animated:animated completion:nil];
    }
    [self preparePageBuffer];
}

[self.pdfReaderViewController setViewControllers:@[self.pdfCurrentViewController] direction:UIPageViewControllerNavigationDirectionForward animated:animated completion:nil];
第一個(gè)參數(shù)是 UIViewController 的 Array飞涂,作為 UIPageViewController 數(shù)據(jù)的 buffer,第二個(gè)和第三個(gè)參數(shù)當(dāng)然是供做動(dòng)畫(huà)使用了祈搜。
這里作為 data 的 array 我只傳了一個(gè) ViewController较店,是因?yàn)?UIPageViewController 有 UIPageViewControllerDataSource 這個(gè)代理可以動(dòng)態(tài)的提供 buffer 數(shù)據(jù)。當(dāng)然了容燕,buffer 的具體內(nèi)容還是要自己生成的梁呈,我的代碼中有 [self preparePageBuffer]; 這個(gè)方法根據(jù)成員變量 _currentPageNum 來(lái)生成顯示前一頁(yè)和后一頁(yè)的 UIViewController,這里翻頁(yè)之后蘸秘,當(dāng)然要調(diào)用一下啦官卡。

  1. 更新 buffer
- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{    
    if (self.pdfPreviousViewController != nil) {
        PDFContentViewController* tmpPage = self.pdfPreviousViewController;
        return tmpPage;
    }
    return nil;
}

- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
    if (self.pdfNextViewController != nil) {
        PDFContentViewController* tmpPage = self.pdfNextViewController;
        return tmpPage;
    }
    return nil;
}

這兩個(gè)方法就是 delegate 里面動(dòng)態(tài)提供頁(yè)面 buffer 的方法了。
這里需要注意的是:
返回的頁(yè)面應(yīng)該是當(dāng)前顯示頁(yè)面下一頁(yè)的下一頁(yè)
解釋一下:如果當(dāng)前顯示的頁(yè)面是 “3”醋虏,那么- (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController 應(yīng)該返回第 “5” 頁(yè)寻咒。
這樣做的原因就是,手勢(shì)翻動(dòng)第三頁(yè)的時(shí)候颈嚼,第四頁(yè)內(nèi)容已經(jīng)露出來(lái)了毛秘,要做動(dòng)畫(huà)效果么,那么 buffer 里面當(dāng)然應(yīng)該放第五頁(yè)嘍,這樣才能實(shí)現(xiàn)連續(xù)的翻頁(yè)效果叫挟。
那么艰匙,

  1. 生成新的 buffer
    這里跟上面是一起的,上面只是用生成好的頁(yè)面刷新 UIPageViewController 的 buffer抹恳,這里才是生成頁(yè)面的代碼员凝。
- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers{
    for (UIViewController* vc in pageViewController.viewControllers) {
        if ([vc isKindOfClass:[PDFContentViewController class]]) {
            PDFContentViewController* tmpvc = (PDFContentViewController*)vc;
            [tmpvc resumeScale];
        }
    }
    if (pendingViewControllers.count > 0) {
        PDFContentViewController* currentPage = (PDFContentViewController*)[pendingViewControllers lastObject];
        _currentPageNum = currentPage.pageNumber;
        [self preparePageBuffer];
    }
}

每次翻頁(yè)的時(shí)候,都會(huì)回調(diào)這個(gè)方法奋献。這里面 pendingViewControllers 參數(shù)傳入的是即將顯示的頁(yè)面健霹。比如說(shuō):當(dāng)前閱讀的是第三頁(yè),然后向后翻頁(yè)秽荞,pendingViewControllers 這個(gè)參數(shù)傳來(lái)的是第四頁(yè)骤公。這個(gè)時(shí)候,需要刷新 buffer 提前將第五頁(yè)生成扬跋。
之所以 pendingViewControllers 這里是 NSArray阶捆,是因?yàn)?UIPageViewController 在上下翻頁(yè)的時(shí)候,可能一次顯示多個(gè)頁(yè)面钦听。(我的項(xiàng)目實(shí)現(xiàn)的是左右翻頁(yè)洒试,這個(gè) NSArray 里面每次只包含一個(gè)頁(yè)面)。
如果一次翻好幾頁(yè)朴上,這個(gè)方法也會(huì)調(diào)用幾次垒棋,只要每次都生成 buffer 提供給 UIPageViewController 就能實(shí)現(xiàn)連續(xù)翻頁(yè)的效果。

  1. 處理一下放棄翻頁(yè)的情況
    有時(shí)候痪宰,用戶翻頁(yè)到一半放棄了叼架,這時(shí)候就需要特殊處理一下。
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed{    
    if (finished == YES && completed == NO) {
        if (previousViewControllers.count > 0) {
            PDFContentViewController* currentPage = (PDFContentViewController*)[previousViewControllers lastObject];
            _currentPageNum = currentPage.pageNumber;
            [currentPage resumeScale];
            [self preparePageBuffer];
        }
    }
}

當(dāng)翻頁(yè)動(dòng)畫(huà)完成后衣撬,會(huì)回調(diào)這個(gè)方法乖订。completed 參數(shù)就是表示用戶是否完成了翻頁(yè)(completed == NO 其實(shí)就是 Gesture 變成了 Cancel 狀態(tài))。
如果沒(méi)有完成翻頁(yè)具练,需要刷新一下 buffer乍构。

解決 UIScrollView 與翻頁(yè)之間的沖突

這里需要在翻頁(yè)之前把 UIScrollview 的 scale 恢復(fù)成1,否則看起來(lái)怪怪的扛点。
有兩種情況哥遮,一個(gè)是 UIScrollview 在放大狀態(tài)點(diǎn)擊翻頁(yè),另一個(gè)是橫屏的時(shí)候陵究,UIScrollview 與橫向充滿屏幕眠饮,這個(gè)時(shí)候也處于放大狀態(tài),但是可以出發(fā)滑動(dòng)翻頁(yè)铜邮。
這個(gè)暫時(shí)的解決方案就是在- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers 里面君仆,把 UIScrollview 的 scale 設(shè)置成1

- (void)resumeScale{
    [self.pdfContentContainerView setZoomScale:1 animated:NO];
}

但是在橫屏狀態(tài)下,偶爾出現(xiàn) UIScrollview 的 anchorpoint 錯(cuò)誤的情況,留待以后解決吧返咱。

下載 PDF 文件的頁(yè)面

這里就是另一個(gè)話題了這篇文章就先不講了:-D

關(guān)于 PDF 閱讀器內(nèi)存泄露的問(wèn)題

感謝小伙伴抽出寶貴時(shí)間閱讀我的代碼并指出內(nèi)存泄露的問(wèn)題
嘗試修復(fù)了一下幾個(gè)地方來(lái)解決這個(gè)問(wèn)題。

- (void)dealloc{
    //確定了,使用CGPDFDocumentRelease釋放 PDFDocument 時(shí)候,會(huì)將 PDFPage 一起釋放
    //好奇怪的設(shè)計(jì) https://stackoverflow.com/questions/46903182/cgcontextdrawpdfpage-memory-leak-app-crash
    if (_pdfDocument != nil) {
        CGPDFDocumentRelease(_pdfDocument);
        _pdfDocument = nil;
    }

}
- (PDFContentViewController* _Nullable)showPage:(size_t)pageNum{
    if (_totalPageNum > 0 && pageNum <= _totalPageNum && pageNum > 0) {
//讀取不同的 pdf 頁(yè)時(shí)牍鞠,不需要將舊的頁(yè)面釋放咖摹,這個(gè)工作由系統(tǒng)在 CGPDFDocumentGetPage 中完成
//        if (_currentPage != nil) {
//            CGPDFPageRelease(_currentPage);
//            _currentPage = nil;
//        }
        _currentPage = CGPDFDocumentGetPage(_pdfDocument, pageNum);
        PDFContentViewController* pdfContentViewController = [[PDFContentViewController alloc]init];
        [pdfContentViewController showPdfPage:_currentPage];
        pdfContentViewController.pageNumber = pageNum;
        return pdfContentViewController;
    }else{
        return nil;
    }
}
#pragma CALayerDelegate
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context{
        //這里是怕異步渲染時(shí),self 突然被釋放掉造成崩潰(這個(gè)方法并不是閉包难述,所以不會(huì)自動(dòng)捕獲引用的變量)
        PDFContentViewController* strongSelf = self;
        //同理萤晴,防止繪制時(shí),pdfPage 被釋放
        CGPDFPageRetain(_pdfPage);
        double screenScale = [UIScreen mainScreen].scale;
        CGSize pdfPageOriginalPageSize = CGPDFPageGetBoxRect(strongSelf->_pdfPage, PDFContentDefaultPDFBox).size;
        CGSize imageSize = CGSizeMake(layer.bounds.size.width, layer.bounds.size.height);
        CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextFillRect(context,CGContextGetClipBoundingBox(context));
        CGContextSaveGState(context);
        CGContextTranslateCTM(context, 0, layer.bounds.size.height);
        CGContextScaleCTM(context, 1, -1);
        
        CGContextScaleCTM(context, imageSize.width/(pdfPageOriginalPageSize.width > 0?pdfPageOriginalPageSize.width:imageSize.width), imageSize.height/(pdfPageOriginalPageSize.height > 0?pdfPageOriginalPageSize.height:imageSize.height));
        //    CGContextScaleCTM(context, 1/screenScale, 1/screenScale);
        CGContextDrawPDFPage(context, strongSelf->_pdfPage);
        CGContextRestoreGState(context);
        CGPDFPageRelease(_pdfPage);
}

根據(jù) StackOverFlow 上面的說(shuō)法胁后,CGPDFDocumentGetPage 為了快速讀取 PDF 頁(yè)面店读,是有緩存的,通過(guò)打印內(nèi)存地址也印證了這個(gè)說(shuō)法攀芯。這就是手動(dòng)釋放 PDFPage 對(duì)象總是崩潰的原因屯断。
http://stackoverflow.com/questions/13248282/uipageviewcontroller-transition-unbalanced-calls-to-begin-end-appearance-transi
http://blog.csdn.net/lqq200912408/article/details/50412893

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市侣诺,隨后出現(xiàn)的幾起案子殖演,更是在濱河造成了極大的恐慌,老刑警劉巖年鸳,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趴久,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡搔确,警方通過(guò)查閱死者的電腦和手機(jī)彼棍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)膳算,“玉大人座硕,你說(shuō)我怎么就攤上這事∑璐保” “怎么了坎吻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)宇葱。 經(jīng)常有香客問(wèn)我瘦真,道長(zhǎng),這世上最難降的妖魔是什么黍瞧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任怀跛,我火速辦了婚禮吸耿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己遣耍,他們只是感情好狡逢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般咸产。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仲闽,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天脑溢,我揣著相機(jī)與錄音,去河邊找鬼赖欣。 笑死屑彻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顶吮。 我是一名探鬼主播社牲,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼悴了!你這毒婦竟也來(lái)了搏恤?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤让禀,失蹤者是張志新(化名)和其女友劉穎挑社,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體巡揍,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痛阻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腮敌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阱当。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖糜工,靈堂內(nèi)的尸體忽然破棺而出弊添,到底是詐尸還是另有隱情,我是刑警寧澤捌木,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布油坝,位于F島的核電站,受9級(jí)特大地震影響刨裆,放射性物質(zhì)發(fā)生泄漏澈圈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一帆啃、第九天 我趴在偏房一處隱蔽的房頂上張望瞬女。 院中可真熱鬧,春花似錦努潘、人聲如沸诽偷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)报慕。三九已至深浮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卖子,已是汗流浹背略号。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洋闽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓突梦,卻偏偏與公主長(zhǎng)得像诫舅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宫患,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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

  • 0 最近項(xiàng)目中需要給客戶看一些比較私密的文件娃闲,為了防止盜取和篡改虚汛,需要用 PDF 格式,為 app 添加了一個(gè)簡(jiǎn)單...
    Tatinic閱讀 2,160評(píng)論 1 2
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)皇帮、插件卷哩、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評(píng)論 4 62
  • 拜讀了林莘老師的《在改變和反思中前行》,破冰之旅属拾,艱難并幸福著将谊。 周四那天,參加女兒的家長(zhǎng)開(kāi)放日活動(dòng)渐白!聽(tīng)的是堂數(shù)學(xué)...
    肺話連篇閱讀 448評(píng)論 0 4
  • 一簾煙雨尊浓,一剪月色,一徑花香纯衍,素淡綿長(zhǎng)的光陰栋齿,從心間緩緩流過(guò)。不留戀車(chē)馬喧囂襟诸,也不艷羨俗世繁華瓦堵,卻安于細(xì)水流年,清...
    雜話漫談閱讀 470評(píng)論 0 1
  • 就比如励堡,今夜谷丸,昨夜,很多個(gè)夜晚应结,你不困刨疼。你想找到的遠(yuǎn)方泉唁,不再是原來(lái),不能忍受揩慕。你好久沒(méi)說(shuō)話亭畜。然后,你終于再開(kāi)口迎卤。遠(yuǎn)...
    浮于浮生閱讀 240評(píng)論 0 0