iOS13-新特性(PDF/Search/Menus)

未經(jīng)授權(quán)慢洋,禁止轉(zhuǎn)載
原文:http://www.reibang.com/p/01cda53e2fc8

轉(zhuǎn)眼間 WWDC 19 已經(jīng)過(guò)去1個(gè)多月了航邢,這篇文章本應(yīng)該很早就寫(xiě)的愤钾,但是有些代碼 beta1-beta4 一個(gè) beta 變一次 API笛丙,而且之前幾個(gè) beta 部分初始化方法還是以 __ 開(kāi)頭的私有方法(無(wú)力吐槽)嫉鲸,所以拖到現(xiàn)在 beta4 API 基本穩(wěn)定了才開(kāi)始寫(xiě)這篇文章。

目錄

  • PDF
  • Gestures
  • Presentations
  • Search
  • Menus

PDF(長(zhǎng)圖)

如果你已經(jīng)升到 iOS 13 你會(huì)發(fā)現(xiàn)當(dāng)你在 Safari 中截圖后有一個(gè) “整頁(yè)” 的功能棵磷,可以把當(dāng)前的 HTML 轉(zhuǎn)成 PDF 存到 “文件” 中蛾狗。那么你可能會(huì)想了,這個(gè)新特性雨窩無(wú)瓜啊泽本,我又不做瀏覽器的 App淘太。其實(shí)我們可以把 scrollView 轉(zhuǎn)成 image,再把 image 轉(zhuǎn)成 PDF规丽,這樣我們就可以把這個(gè) scrollView 做成一個(gè)長(zhǎng)圖了箕般,我們先來(lái)看下效果第队。

注.我將pdf轉(zhuǎn)成了jpeg

怎么樣是不是挺不錯(cuò)的兵迅,接下來(lái)就讓我們來(lái)看看這是怎么實(shí)現(xiàn)的甜紫。
首先我們要在控制器中實(shí)現(xiàn) UIScreenshotServiceDelegate 代理,由于 iOS 13 項(xiàng)目結(jié)構(gòu)發(fā)生了變化艘狭,這里列出兩種設(shè)置代理的方式挎扰。

// iOS 13項(xiàng)目結(jié)構(gòu)
let scene = UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate
scene?.window?.windowScene?.screenshotService?.delegate = self

// iOS13之前項(xiàng)目結(jié)構(gòu)
UIApplication.shared.keyWindow?.windowScene?.screenshotService?.delegate = self

UIScreenshotServiceDelegate 代理只有一個(gè)方法,讓我們來(lái)實(shí)現(xiàn)它

func screenshotService(_ screenshotService: UIScreenshotService, generatePDFRepresentationWithCompletion completionHandler: @escaping (Data?, Int, CGRect) -> Void) {
    completionHandler(getScreenshotData(tableView), 0, CGRect.zero)
}

我們看一下這個(gè)回調(diào)巢音,第一個(gè)參數(shù)是 PDF 的 data 數(shù)據(jù)遵倦,第二個(gè)參數(shù)是 PDF 頁(yè)面的索引,第三個(gè)參數(shù)是 PDF 中相對(duì)于當(dāng)前頁(yè)面的坐標(biāo)官撼。getScreenshotData 是我自己寫(xiě)的方法梧躺,方法里的邏輯是 scrollView → image → PDF → data,由于代碼不多傲绣,而且都能在網(wǎng)上找到掠哥,就不貼出來(lái)了。
說(shuō)一下思路秃诵,scrollView 轉(zhuǎn)成 image 的原理是 scrollView.frame = CGRect(origin: .zero, size: scrollView.contentSize)
注意:如果是 tableView 的話(huà)會(huì)導(dǎo)致所有 cell 都被加載出來(lái)续搀,如果當(dāng)前控制器是一個(gè)無(wú)限列表,請(qǐng)不要使用這個(gè)功能菠净。

Gestures

雙指滑動(dòng)手勢(shì)

iOS 13 中 tableViewcollectionView 都增加雙指滑動(dòng)編輯的功能禁舷,在短信和備忘錄中都使用這個(gè)功能彪杉,接下來(lái)我們來(lái)看下效果。

這個(gè)功能體驗(yàn)上也是很爽的榛了,如果你的 App 中有相應(yīng)的場(chǎng)景在讶,建議加上這個(gè)功能煞抬,下面讓我們一起來(lái)看看怎么實(shí)現(xiàn)這個(gè)效果霜大。
首先設(shè)置 tableView.allowsMultipleSelectionDuringEditing = true 允許多選,然后實(shí)現(xiàn)兩個(gè)代理方法革答。

/// 是否允許多指選中
optional func tableView(_ tableView: UITableView, shouldBeginMultipleSelectionInteractionAtIndexPath indexPath: IndexPath) -> Bool

///多指選中開(kāi)始战坤,這里可以做一些UI修改,比如修改導(dǎo)航欄上按鈕的文本
optional func tableView(_ tableView: UITableView, didBeginMultipleSelectionInteractionAtIndexPath indexPath: IndexPath) 

最后當(dāng)用戶(hù)選擇完残拐,要做某些操作的時(shí)候途茫,我們可以用 tableView.indexPathsForSelectedRows 獲取用戶(hù)選擇的 rows。

編輯手勢(shì)

  • 復(fù)制:三指捏合
  • 剪切:兩次三指捏合
  • 粘貼:三指松開(kāi)
  • 撤銷(xiāo):三指向左劃動(dòng)(或三指雙擊)
  • 重做:三指向右劃動(dòng)
  • 快捷菜單:三指單擊

iOS 13 增加了一些文本編輯的手勢(shì)溪食,這些手勢(shì)系統(tǒng)默認(rèn)會(huì)提供囊卜,如果我們想要禁用這些手勢(shì),需要重寫(xiě) editingInteractionConfiguration 屬性错沃,代碼如下栅组。

override var editingInteractionConfiguration: UIEditingInteractionConfiguration {
    return .none
}

Presentations

iOS 13 下 present 的效果改成了這個(gè)樣子。


這樣帶來(lái)了新的交互方式枢析,下拉就可以 dismiss 控制器玉掸,實(shí)測(cè)這是個(gè)很爽的功能,體驗(yàn)大幅度提升醒叁,但是對(duì)我們開(kāi)發(fā)者來(lái)說(shuō)呢司浪,帶來(lái)了一些坑,下面讓我們來(lái)看看吧把沼。

首先 UIModalPresentationStyle 增加了一個(gè) automatic 屬性啊易,在 iOS 13 下默認(rèn)就是這個(gè)屬性。系統(tǒng)會(huì)根據(jù)推出的控制器來(lái)選擇是 pageSheet 還是 fullScreen饮睬,比如當(dāng)我們用 UIImagePickerController 推出相機(jī)是 fullScreen租谈,我們自己寫(xiě)的控制器是 pageSheet。如果我們只想推出 fullScreen 的控制器也很簡(jiǎn)單续捂,present 之前設(shè)置 vc.modalPresentationStyle = .fullScreen 就好了垦垂。

接下來(lái)說(shuō)一下 pageSheet 的坑是什么,我們先來(lái)看下 fullScreen 的調(diào)用順序牙瓢。

fullScreen

再來(lái)看下 pageSheet 的調(diào)用順序劫拗。

pageSheet

當(dāng)A控制器 present B控制器,A控制器的 viewWillDisappearviewDidDisappear 不會(huì)調(diào)用矾克,當(dāng)B控制器 dismiss页慷,A控制器的 viewWillAppearviewDidAppear 也不會(huì)調(diào)用。也就是說(shuō)如果你有一些邏輯是放在這4個(gè)方法中的,要么把業(yè)務(wù)邏輯換個(gè)地方酒繁,要么設(shè)置 vc.modalPresentationStyle = .fullScreen滓彰。

另外,UIViewController 增加一個(gè)了屬性 isModalInPresentation州袒,默認(rèn)為 false揭绑,當(dāng)該屬性為 false 時(shí),用戶(hù)下拉可以 dismiss 控制器郎哭,為 true 時(shí)他匪,下拉不可以 dismiss控制器。該屬性可以配合有編輯功能的控制器使用夸研,讓我們來(lái)看下官方的 Demo

我們可以看到邦蜜,未編輯內(nèi)容時(shí)下拉可以 dismiss,編輯了內(nèi)容后下拉不可以dismiss亥至,同時(shí)彈出了一個(gè) alert 提示用戶(hù)要不要保存編輯過(guò)的內(nèi)容悼沈。詳細(xì)的代碼大家可以去 Demo 里看,這里就簡(jiǎn)單說(shuō)一下姐扮。
首先判斷用戶(hù)是否輸入絮供,有輸入將 isModalInPresentation 改為 true。然后實(shí)現(xiàn) UIAdaptivePresentationControllerDelegate 代理的 presentationControllerDidAttemptToDismiss: 方法溶握。這個(gè)方法會(huì)在 isModalInPresentation = true杯缺,且用戶(hù)嘗試下拉 dismiss 控制器時(shí)調(diào)用。最后在這個(gè)方法里彈出 alert 提示用戶(hù)是否保存編輯過(guò)的內(nèi)容即可睡榆。

Search

iOS 13 下 UISearchViewController 結(jié)構(gòu)如下萍肆。


我們先來(lái)說(shuō)下 UISearchBar 的變化,現(xiàn)在我們可以在 UISearchBar 中獲取到 UISearchTextField 了胀屿,可以修改 field 的顏色塘揣、字體等,代碼如下宿崭。

let field = searchController.searchBar.searchTextField
field.textColor = UIColor.label
field.font = UIFont.systemFont(ofSize: 20)

其次增加了 Token 功能亲铡,Token 可以被復(fù)制、粘貼和拖拽葡兑,Token 還具有以下特點(diǎn):
1.始終在普通文本前面奖蔓;
2.可以被選中和刪除;
3.可以和普通文本一起被選中讹堤;


接下來(lái)我們看下如何創(chuàng)建 Token吆鹤,我們有兩種創(chuàng)建 Token 的方式,代碼如下洲守。

// 第一種方式疑务,直接創(chuàng)建一個(gè) Token
let field = searchController.searchBar.searchTextField
field.insertToken(UISearchToken(icon: nil, text: "Token"), at: 0)

// 第二種方式沾凄,選擇一段文本,將其變成 Token知允,過(guò)程如圖
let field = searchController.searchBar.searchTextField
guard let selectedTextRange = field.selectedTextRange, !selectedTextRange.isEmpty else { return }
guard let selectedText = field.text(in: selectedTextRange) else { return } // "beach"
let token = UISearchToken(icon: nil, text: selectedText)
field.replaceTextualPortion(of: selectedTextRange, with: token, at: field.tokens.count)


此外撒蟀,系統(tǒng)還提供 textualRange 屬性,來(lái)獲取普通文本的長(zhǎng)度温鸽。

最后介紹一下 showsSearchResultsController 屬性保屯,該屬性可以控制是否展示搜索結(jié)果控制器。

Menus

還記得我在文章開(kāi)頭說(shuō)有些 API 一個(gè) beta 改一次嘛...沒(méi)錯(cuò)就是它 UIMenu 每個(gè) beta 寫(xiě)法都不一樣(吃棗藥丸)我們先來(lái)看下效果嗤朴。

我們分析一下動(dòng)圖里的結(jié)構(gòu)配椭,如圖


我們可以看到 UIMenu 可以嵌套 UIAction 也可以再嵌套 UIMenu虫溜,下面讓我們一起來(lái)看看這是怎么實(shí)現(xiàn)的雹姊。
首先創(chuàng)建一個(gè) UIContextMenuInteraction 對(duì)象,將它加到對(duì)應(yīng)的 view 上衡楞。

let menuInteraction = UIContextMenuInteraction(delegate: self)
menuView.addInteraction(menuInteraction)

其次實(shí)現(xiàn) UIContextMenuInteractionDelegate 代理吱雏,配置 UIMenu

func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
    return UIContextMenuConfiguration(identifier: nil, previewProvider: { () -> UIViewController? in
        // 需要展示的控制器
        return ViewController2()
    }) { (list) -> UIMenu? in
        let editMenu = UIMenu(title: "Edit...", image: nil, identifier: nil, options: [], children: [
            UIAction(title: "Copy", image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { (_) in
                print("Copy")
            }),
            UIAction(title: "Duplicate", image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { (_) in
                print("Duplicate")
            })
        ])
        
        return UIMenu(title: "", image: nil, identifier: nil, options: [], children: [
            UIAction(title: "Share", image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { (_) in
                print("Share")
            }),
            editMenu,
            UIAction(title: "Delete", image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [.destructive], state: .off, handler: { (_) in
                print("Delete")
            })
        ])
    }
}

代碼有點(diǎn)多瘾境,但是不難歧杏,我們一點(diǎn)點(diǎn)來(lái)分析,另外圖片相關(guān)的代碼我刪掉了迷守,沒(méi)太多意義還會(huì)影響閱讀體驗(yàn)犬绒。
首先這個(gè)方法要求我們返回一個(gè) UIContextMenuConfiguration 對(duì)象,這個(gè)對(duì)象的初始化方法有3個(gè)參數(shù)兑凿,第一個(gè)是 identifier凯力,第二個(gè)是一個(gè)閉包,要求返回要展示的控制器礼华,第三個(gè)也是個(gè)閉包咐鹤,要求返回 UIMenu 對(duì)象。

UIMenu

接下來(lái)我們看下 UIMenu 創(chuàng)建的過(guò)程圣絮, 首先創(chuàng)建了 editMenu 也就是動(dòng)圖中第二欄祈惶,點(diǎn)擊之后會(huì)再?gòu)棾鰞蓚€(gè) UIAction,然后讓我們看看怎么創(chuàng)建 UIMenu扮匠。

init(title: String, 
     image: UIImage? = nil, 
     identifier: UIMenu.Identifier? = nil, 
     options: UIMenu.Options = [], 
     children: [UIMenuElement] = [])

這里我們主要說(shuō)下 options 參數(shù)捧请,UIMenu.Options 聲明如下。

public struct Options : OptionSet {
    public init(rawValue: UInt)
    /// Show children inline in parent, instead of hierarchically
    public static var displayInline: UIMenu.Options { get }
    /// Indicates whether the menu should be rendered with a destructive appearance in its parent
    public static var destructive: UIMenu.Options { get }
}

options 參數(shù)是用于第二層 menu 的棒搜,我們可以看到動(dòng)圖中的 Delete 是紅色的疹蛉,那是因?yàn)樗?UIAction 而且有對(duì)應(yīng)的屬性可以設(shè)置,那么如果我想把 Edit... 弄成成紅色就要設(shè)置 options = destructive帮非。再說(shuō)下 displayInline氧吐,這個(gè)效果是把第二層 menu 放到第一層來(lái)展示讹蘑,效果如下。

細(xì)心的小伙伴可能發(fā)現(xiàn)筑舅,options 是一個(gè) OptionSet 意味著可以同時(shí)設(shè)置兩個(gè)屬性座慰,那么設(shè)置兩個(gè)屬性會(huì)有什么效果呢,答案是:只有 displayInline 的效果翠拣,做成 OptionSet 應(yīng)該是為將來(lái)拓展用的版仔,目前是沒(méi)什么用的。

UIAction

接下來(lái)我們來(lái)看看 UIAction 的初始化方法误墓。

init(title: String, 
     image: UIImage? = nil, 
     identifier: UIAction.Identifier? = nil, 
     discoverabilityTitle: String? = nil, 
     attributes: UIMenuElement.Attributes = [], 
     state: UIMenuElement.State = .off, 
     handler: @escaping UIActionHandler)

前三個(gè)參數(shù)就不說(shuō)了蛮粮,第四個(gè)參數(shù) discoverabilityTitle 這個(gè)參數(shù)我目前沒(méi)有研究出來(lái)是干嘛用的,如果有知道的小伙伴歡迎在評(píng)論區(qū)留言谜慌。
第五個(gè)參數(shù) attributes然想,我們先來(lái)看下聲明和效果圖。

public struct Attributes : OptionSet {
    public init(rawValue: UInt)
    public static var disabled: UIMenuElement.Attributes { get }
    public static var destructive: UIMenuElement.Attributes { get }
    public static var hidden: UIMenuElement.Attributes { get }
}

attributes 也是 OptionSet 可以多個(gè)一起用欣范,但是這幾個(gè)組合都沒(méi)用变泄。

第六個(gè)參數(shù) state,一樣先看聲明和效果圖恼琼。

public enum State : Int {
    case off
    case on
    case mixed
}


state 可以和 attributes 搭配使用妨蛹,onmixed 的區(qū)別我目前沒(méi)找到,另外如果 UIAction 設(shè)置了圖片同時(shí)設(shè)置了 state = .on 則會(huì)把圖片覆蓋掉晴竞,只留下一個(gè)勾勾蛙卤。
第七個(gè)參數(shù)是個(gè)閉包,當(dāng)用戶(hù)點(diǎn)擊后會(huì)進(jìn)入回調(diào)噩死,處理相應(yīng)的邏輯即可颤难。
最后我們把 UIAction 和 editMenu 一起放到一個(gè)新的 UIMenu 中就可以達(dá)到動(dòng)圖中的效果了。


以上是 iOS 13 部分新特性的介紹甜滨,如有錯(cuò)誤歡迎指出乐严。
WWDC鏈接 Modernizing Your UI for iOS 13

如果你想知道 iOS 13 怎么適配夜間模式可以閱讀這篇文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衣摩,一起剝皮案震驚了整個(gè)濱河市昂验,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌艾扮,老刑警劉巖既琴,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異泡嘴,居然都是意外死亡甫恩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)酌予,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)磺箕,“玉大人奖慌,你說(shuō)我怎么就攤上這事∷擅遥” “怎么了简僧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)雕欺。 經(jīng)常有香客問(wèn)我岛马,道長(zhǎng),這世上最難降的妖魔是什么屠列? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任啦逆,我火速辦了婚禮,結(jié)果婚禮上笛洛,老公的妹妹穿的比我還像新娘夏志。我一直安慰自己,他們只是感情好撞蜂,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布盲镶。 她就那樣靜靜地躺著,像睡著了一般蝌诡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枫吧,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天浦旱,我揣著相機(jī)與錄音,去河邊找鬼九杂。 笑死颁湖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的例隆。 我是一名探鬼主播甥捺,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼镀层!你這毒婦竟也來(lái)了镰禾?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤唱逢,失蹤者是張志新(化名)和其女友劉穎吴侦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體坞古,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡备韧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痪枫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片织堂。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叠艳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出易阳,到底是詐尸還是另有隱情虑绵,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布闽烙,位于F島的核電站翅睛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏黑竞。R本人自食惡果不足惜捕发,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望很魂。 院中可真熱鬧扎酷,春花似錦、人聲如沸遏匆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)幅聘。三九已至凡纳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帝蒿,已是汗流浹背荐糜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留葛超,地道東北人暴氏。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像绣张,于是被迫代替她去往敵國(guó)和親答渔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • 掌握 UIScrollView的常見(jiàn)屬性 UIScrollView的常用代理方法 UIScrollView的縮放 ...
    JonesCxy閱讀 2,715評(píng)論 1 12
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類(lèi)型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,089評(píng)論 1 32
  • 【感想】:自己就存在認(rèn)知偏差這種觀念侥涵。在沒(méi)有參加媛創(chuàng)讀書(shū)會(huì)之前沼撕,由于很少讀書(shū),自己的世界觀存在一定的偏差独令。每天面對(duì)...
    西風(fēng)瘦馬_25c2閱讀 370評(píng)論 0 0
  • 最近導(dǎo)師出差一周端朵,我和脫了韁的野馬一樣開(kāi)心又緊張,一邊在宿舍聽(tīng)歌一邊處理屎一樣的數(shù)據(jù)燃箭,一邊在影院看狂暴巨獸一邊擔(dān)心...
    二爺周記閱讀 1,595評(píng)論 10 2
  • 做攻略冲呢、定旅館、買(mǎi)車(chē)票招狸, READY敬拓,GO邻薯! 網(wǎng)購(gòu)的是周六上午6:30福州到廈門(mén)的動(dòng)車(chē)票,5:20就睡不著了乘凸,起床...
    懶懶的無(wú)尾熊閱讀 549評(píng)論 0 5