馬上著手開發(fā) iOS 應(yīng)用程序 (十) - 實(shí)現(xiàn)編輯和刪除功能

重要:這是針對(duì)于正在開發(fā)中的API或技術(shù)的預(yù)備文檔(預(yù)發(fā)布版本)囚霸。蘋果提供這份文檔的目的是幫助你按照文中描述的方式對(duì)技術(shù)的選擇及界面的設(shè)計(jì)開發(fā)進(jìn)行規(guī)劃拓型。這些信息有可能發(fā)生變化,因此根據(jù)本文檔的軟件開發(fā)應(yīng)當(dāng)基于最終版本的操作系統(tǒng)和文檔進(jìn)行測(cè)試册养。該文檔的新版本或許會(huì)隨著API或相關(guān)技術(shù)未來的發(fā)展而進(jìn)行更新揣云。

翻譯自蘋果官網(wǎng):

https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson9.html#//apple_ref/doc/uid/TP40015214-CH9-SW1

本課中,集中精力添加功能讓用戶在 app 中能編輯和刪除美食刘莹。

學(xué)習(xí)目標(biāo)

在本課的最后焚刚,你將能夠:

  • 區(qū)別 push 和 modal 導(dǎo)航
  • 基于視圖控制器的打開方式關(guān)閉它們
  • 理解何時(shí)使用不同的向下轉(zhuǎn)換的方式
  • 利用可選綁定來檢查復(fù)雜的條件
  • 使用 segue 標(biāo)識(shí)確定哪個(gè) segue 正在發(fā)生矿咕。

允許編輯已存在的美食

現(xiàn)在,F(xiàn)oodTracker app 讓用戶能夠向食物列表添加一份新的食物捡絮。下一步莲镣,讓用戶能夠編輯已存在的食物。

用戶點(diǎn)擊單元格打開一個(gè)用食物信息填充的場(chǎng)景的圆。用戶修改然后點(diǎn)擊 Save 按鈕,更新信息并覆寫食物列表中對(duì)應(yīng)對(duì)象季俩。

配置 table view 單元格
  1. 如果輔助編輯器打開了梅掠,點(diǎn)擊 Standard 按鈕返回標(biāo)準(zhǔn)編輯器瓤檐。

    [圖片上傳失敗...(image-f118a-1608214610979)]

  2. 打開 Main.storyboard娱节。

  3. 在畫板中,選擇 table view cell谴古。

  4. 按住 Control 從 table view cell 拖動(dòng)到美食場(chǎng)景稠歉。

    [圖片上傳失敗...(image-c0d85f-1608214610979)]

    在拖動(dòng)結(jié)束的位置彈出標(biāo)題為 Selection Segue 的快捷菜單怒炸。

    [圖片上傳失敗...(image-a9a69f-1608214610979)]

  5. 選擇菜單中的 show。

  6. 在食物列表和食物場(chǎng)景間拖動(dòng)勺疼,松開后會(huì)看到新的 segue捏鱼。

    [圖片上傳失敗...(image-e07768-1608214610979)]

    使用 Command+減號(hào)(-)縮小畫板导梆。

  7. 選擇畫板中新加的 segue。

    [圖片上傳失敗...(image-184310-1608214610979)]

  8. 在屬性檢查器中的 Identifier 區(qū)域輸入 ShowDetail递鹉〔卣叮回車確認(rèn)灾茁。

    [圖片上傳失敗...(image-2772be-1608214610979)]

當(dāng) segue 觸發(fā)了谷炸,push 食物視圖控制器到食物列表場(chǎng)景所在的導(dǎo)航棧中旬陡。

檢驗(yàn):運(yùn)行 app语婴。在食物列表場(chǎng)景,你應(yīng)該能夠點(diǎn)擊一個(gè) table view cell 來導(dǎo)航到食物場(chǎng)景匿醒,但是場(chǎng)景的內(nèi)容是空的廉羔。當(dāng)你點(diǎn)擊 table view 中已經(jīng)存在的單元格時(shí)候僻造,你想要的是編輯它,而不是創(chuàng)建一個(gè)新的竹挡。

現(xiàn)在有兩個(gè) segue 能跳到相同的場(chǎng)景了立膛,所以你需要一種方法來區(qū)別添加一份新的食物或者編輯已存在的這兩種情況。

回憶之前任何 segue 執(zhí)行前都會(huì)被調(diào)用的 prepareForSegue(_:sender:) 方法好啰。你可以使用這個(gè)方法來區(qū)別哪個(gè) segue 正在執(zhí)行鲁猩,然后在食物場(chǎng)景中顯示合適的信息廓握。使用之前設(shè)給它們的 identifiers 來區(qū)分 segues。AddItem(model segue)和 ShowDeatil(show segue)男应。

區(qū)分哪個(gè) segue 在執(zhí)行
  1. 打開 MealTableViewController.swift娱仔。

  2. 在 MealTableViewController.swift 中,找到并取消 prepareForSegue(_:sender:) 方法的注釋耐朴。

    (為了取消方法的注釋筛峭,移除周圍的 /* 和 */ 字符。)

    當(dāng)你做完這些后镰吵,模板默認(rèn)實(shí)現(xiàn)如下:

     // MARK: - Navigation
      
     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
         
         // Get the new view controller using segue.destinationViewController.
         // Pass the selected object to the new view controller.
     }
    
  3. 刪除兩行的注釋疤祭,替換為 if 語(yǔ)句和 else 從句饵婆。

     if segue.identifier == "ShowDetail" {
     }
     else if segue.identifier == "AddItem" {
     }
    

    代碼比較 segue identifier 和之前分配給它們的標(biāo)識(shí)字符串啦辐。

  4. 在 if 語(yǔ)句(如果食物正在被編輯就執(zhí)行)中蜈项,添加如下代碼:

     let mealDetailViewController = segue.destinationViewController as! MealViewController
    

    代碼嘗試使用強(qiáng)制類型轉(zhuǎn)換操作符(as!) 下轉(zhuǎn) segue 的目標(biāo)視圖控制器到 MealViewController紧卒。注意這個(gè)操作符的最后是感嘆號(hào)(!)而不是問號(hào)(?)恨锚。這意味著執(zhí)行了強(qiáng)制類型轉(zhuǎn)換白粉。如果轉(zhuǎn)換成功空猜,將 segue.destinationViewController 轉(zhuǎn)換的 MealViewController 類型的值賦給局部變量 mealDetailViewController。如果轉(zhuǎn)換不成功往堡,app 運(yùn)行時(shí)應(yīng)該崩潰了虑灰。

    只有確認(rèn)轉(zhuǎn)換會(huì)成功才使用強(qiáng)制轉(zhuǎn)換 - 如果失敗痹兜,app 產(chǎn)生錯(cuò)誤并崩潰,否則对湃,請(qǐng)使用 as拍柒? 轉(zhuǎn)換。

  5. 在前一行的下面剧包,添加另一個(gè) if 語(yǔ)句(嵌套在第一個(gè)里面):

     // Get the cell that generated this segue.
     if let selectedMealCell = sender as? MealTableViewCell {
     }
    

    代碼嘗試使用可選類型轉(zhuǎn)換符(as?)轉(zhuǎn)換 sender 給 MealCell往果。如果轉(zhuǎn)換成功陕贮,將 sender 轉(zhuǎn)換的 MealTableViewCell 類型的值賦給本地常量 selectedMealCell 然后 if 語(yǔ)句繼續(xù)執(zhí)行。如果轉(zhuǎn)換不成功掉缺,表達(dá)式值變?yōu)?nil 然后 if 語(yǔ)句不執(zhí)行眶明。

  6. 在 if 語(yǔ)句里面筐高,添加這些代碼:

     let indexPath = tableView.indexPathForCell(selectedMealCell)!
     let selectedMeal = meals[indexPath.row]
     mealDetailViewController.meal = selectedMeal
    

    代碼為 table view 選中的單元格拿到對(duì)應(yīng)的 Meal 對(duì)象柑土。然后賦給目標(biāo)視圖控制器的 meal 屬性。

  7. 在之前添加的 else 從句里面扮宠,添加 print 語(yǔ)句:

     print("Adding new meal.")
    

    盡管添加新的食物時(shí)候此方法不需要做什么事情坛增,但是記錄將要發(fā)生很有用荒叼。

最后的 prepareForSegue(_:sender:) 方法應(yīng)該像這樣:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "ShowDetail" {
        let mealDetailViewController = segue.destinationViewController as! MealViewController
        
        // Get the cell that generated this segue.
        if let selectedMealCell = sender as? MealTableViewCell {
            let indexPath = tableView.indexPathForCell(selectedMealCell)!
            let selectedMeal = meals[indexPath.row]
            mealDetailViewController.meal = selectedMeal
        }
    }
    else if segue.identifier == "AddItem" {
        print("Adding new meal.")
    }
}

現(xiàn)在需要邏輯實(shí)現(xiàn)被廓,你需要在 MealViewController.swift 中做一些工作來確保界面正確的更新了。特別當(dāng) MealViewController 對(duì)象創(chuàng)建后昆婿,它的視圖應(yīng)該被它的 meal 屬性的數(shù)據(jù)填充仓蛆,當(dāng)這些數(shù)據(jù)存在的情況下《共Γ回憶下最合適做這類工作的地方就是在 viewDidLoad() 方法里面了能庆。

更新 viewDidLoad 的實(shí)現(xiàn)
  1. 打開 MealViewController.swift搁胆。

  2. 在 MealViewController.swift 中,找到 viewDidLoad() 方法攀例。

     override func viewDidLoad() {
         super.viewDidLoad()
         
         // Handle the text field’s user input via delegate callbacks.
         nameTextField.delegate = self
         
         // Enable the Save button only if the text field has a valid Meal name.
         checkValidMealName()
     }
    
  3. 在 nameTextField.delegate 行的下面粤铭,添加這些代碼:

     // Set up views if editing an existing Meal.
     if let meal = meal {
         navigationItem.title = meal.name
         nameTextField.text   = meal.name
         photoImageView.image = meal.photo
         ratingControl.rating = meal.rating
     }
    

    如果 meal 屬性非空設(shè)置 MealViewController 的每個(gè)視圖來顯示對(duì)應(yīng)的數(shù)據(jù)承耿,這只在編輯已存在的食物時(shí)候發(fā)生伪煤。

你的 viewDidLoad() 方法應(yīng)該像這樣:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Handle the text field’s user input via delegate callbacks.
        nameTextField.delegate = self
        
        // Set up views if editing an existing Meal.
        if let meal = meal {
            navigationItem.title = meal.name
            nameTextField.text   = meal.name
            photoImageView.image = meal.photo
            ratingControl.rating = meal.rating
        }
        
        // Enable the Save button only if the text field has a valid Meal name.
        checkValidMealName()
    }

檢驗(yàn):運(yùn)行 app抱既。你應(yīng)該能夠點(diǎn)擊一個(gè)單元格導(dǎo)航到食物場(chǎng)景中并看到填充了食物數(shù)據(jù)扁誓。但是如果點(diǎn)擊 Save蝗敢,app 添加了新的食物而不是覆寫已經(jīng)存在的。下一步實(shí)現(xiàn)正確的行為锁右。

[圖片上傳失敗...(image-c0cb01-1608214610979)]

為了覆寫食物列表中已經(jīng)存在的食物咏瑟,你需要更新 unwindToMealList(_:) 方法來處理兩種不同的情況。一種情況兄旬,你需要添加一份新的食物余寥,另一種情況宋舷,你需要替換已經(jīng)存在的那份×ぃ回憶下這個(gè)方法只在用戶點(diǎn)擊保存按鈕的時(shí)候調(diào)用改艇,所以你不需要在這個(gè)方法中處理 Cancel 按鈕坟岔。

更新 unwindToMealList(_:) 實(shí)現(xiàn)來添加或者替換食物
  1. 打開 MealTableViewController.swift社付。

  2. 在 MealTableViewController.swift,找到 unwindToMealList(_:) 方法燕鸽。

     @IBAction func unwindToMealList(sender: UIStoryboardSegue) {
         if let sourceViewController = sender.sourceViewController as? MealViewController, meal = sourceViewController.meal {
             // Add a new meal.
             let newIndexPath = NSIndexPath(forRow: meals.count, inSection: 0)
             meals.append(meal)
             tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
         }
     }
    
  3. 在 if 語(yǔ)句的開頭啊研,添加如下 if 語(yǔ)句:

     if let selectedIndexPath = tableView.indexPathForSelectedRow {
     }
    

    代碼檢查 table view 中的行是否被選中党远。如果選中富弦,意味著用戶點(diǎn)擊其中的一個(gè)單元格來編輯食物。

  4. 在 if 語(yǔ)句中添加如下代碼:

     // Update an existing meal.
     meals[selectedIndexPath.row] = meal
     tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
    

    第一行更新 meals 中對(duì)應(yīng)的食物信息济似。第二行刷新 table view 中合適的行來顯示修改后的數(shù)據(jù)碱屁。

  5. 在 if 語(yǔ)句后面娩脾,添加如下的 else 從句:

     else {
         // Add a new meal.
         let newIndexPath = NSIndexPath(forRow: meals.count, inSection: 0)
         meals.append(meal)
         tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
     }
    

    選擇 else 從句中這些行按 Control-I 確保它們正確縮進(jìn)。
    當(dāng)在 table view 中沒有選中行時(shí)執(zhí)行 else 從句俩功,這意味著用戶點(diǎn)擊增加按鈕來打開食物場(chǎng)景诡蜓。換言之胰挑,就是如果正在添加一份新的食物 else 從句就會(huì)執(zhí)行瞻颂。

最后的 unwindToMealList(_:) 方法應(yīng)該像這樣:

    @IBAction func unwindToMealList(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.sourceViewController as? MealViewController, meal = sourceViewController.meal {
            if let selectedIndexPath = tableView.indexPathForSelectedRow {
                // Update an existing meal.
                meals[selectedIndexPath.row] = meal
                tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
            }
            else {
                // Add a new meal.
                let newIndexPath = NSIndexPath(forRow: meals.count, inSection: 0)
                meals.append(meal)
                tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Bottom)
            }
        }
    }

檢驗(yàn):運(yùn)行 app贡这。你應(yīng)該能夠點(diǎn)擊一個(gè) table view cell 來導(dǎo)航到食物場(chǎng)景并看到它已經(jīng)被食物數(shù)據(jù)填充了。如果你點(diǎn)擊保存丽惭,你做的修改會(huì)覆寫列表中現(xiàn)有的食物责掏。

[圖片上傳失敗...(image-906f1a-1608214610979)]

取消編輯現(xiàn)有的食物

用戶或許決定不再編輯食物了辐马,想在沒有保存任何修改的情況下返回食物列表喜爷。為了做到這點(diǎn)萄唇,更新 Cancel 按鈕的行為來適當(dāng)?shù)年P(guān)閉場(chǎng)景另萤。

關(guān)閉的類型取決于打開時(shí)的類型诅挑。當(dāng)用戶點(diǎn)擊 Cancel 按鈕時(shí)做一個(gè)檢查來決定當(dāng)前場(chǎng)景如何打開的拔妥。如果是模態(tài)打開的(使用 Add 按鈕)达箍,使用 dismissViewControllerAnimated(_:completion:) 關(guān)閉缎玫。如果使用 push 導(dǎo)航打開的(點(diǎn)擊單元格)赃磨,會(huì)被那個(gè)打開它的導(dǎo)航控制器關(guān)閉的。

修改取消方法
  1. 打開 MealViewController.swift溪王。

  2. 在 MealViewController.swift 中莹菱,找到 cancel(_:) 方法雷客。

     @IBAction func cancel(sender: UIBarButtonItem) {
         dismissViewControllerAnimated(true, completion: nil)
     }
    

    當(dāng)前只使用了 dismissViewControllerAnimated 來關(guān)閉食物場(chǎng)景因?yàn)槟隳壳皟H僅為 Add 按鈕做處理了搅裙。

  3. 在 cancel(_:) 方法的最前面行,添加如下代碼:

     // Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
     let isPresentingInAddMealMode = presentingViewController is UINavigationController
    

    代碼創(chuàng)建一個(gè)布爾值表明打開這個(gè)場(chǎng)景視圖控制器是否為 UINavigationController 類型娜汁。正如常量名字 isPresentingInAddMealMode 說明掐禁,這意味著食物場(chǎng)景使用 Add 按鈕打開的傅事。因?yàn)楫?dāng)食物場(chǎng)景以這種方式打開時(shí)候它被嵌入到它自己的導(dǎo)航控制器中峡扩,這意味著是導(dǎo)航控制器打開了它教届。

  4. 在你剛添加的行下面驾霜,添加如下 if 語(yǔ)句粪糙,并且移動(dòng) dismissViewControllerAnimated 那行到它里面:

     if isPresentingInAddMealMode {
         dismissViewControllerAnimated(true, completion: nil)
     }
    

    之前蓉冈,dismissViewControllerAnimated 每次都會(huì)在 cancel(_:) 方法觸發(fā)時(shí)調(diào)用倦卖,現(xiàn)在只在 isPresentingInAddMealMode 是 true 的情況下執(zhí)行怕膛。

  5. 在 if 語(yǔ)句的右邊,添加如下 else 從句:

     else {
         navigationController!.popViewControllerAnimated(true)
     }
    

    現(xiàn)在有 if 語(yǔ)句同時(shí)有個(gè) else 從句掸茅,if 語(yǔ)句中的代碼只會(huì)在 isPresentingInAddMealMode 是 true 的情況下執(zhí)行昧狮,否則執(zhí)行 else 從句的代碼逗鸣。當(dāng)食物場(chǎng)景被 push 到導(dǎo)航棧時(shí) else 從句執(zhí)行绰精。else 從句中代碼調(diào)用 popViewControllerAnimated 從導(dǎo)航棧中彈出當(dāng)前視圖控制器(食物場(chǎng)景)并同時(shí)執(zhí)行一個(gè)過渡動(dòng)畫笨使。

最后的 cancel(_:) 方法應(yīng)該像這樣:

    @IBAction func cancel(sender: UIBarButtonItem) {
        // Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
        let isPresentingInAddMealMode = presentingViewController is UINavigationController
        
        if isPresentingInAddMealMode {
            dismissViewControllerAnimated(true, completion: nil)
        }
        else {
            navigationController!.popViewControllerAnimated(true)
        }
    }

檢驗(yàn):運(yùn)行 app×蛞現(xiàn)在當(dāng)你點(diǎn)擊 Add 按鈕(+)然后點(diǎn)擊 Cancel 而不是 Save靶草,你應(yīng)該導(dǎo)航返回到食物列表了。

支持刪除食物

下一步烤送,讓用戶能夠從食物列表中刪除一份食物帮坚。需要用戶能夠?qū)?table view 變成編輯模式來刪除單元格互艾。通過在 table view 導(dǎo)航欄添加一個(gè)編輯按鈕來完成這個(gè)功能纫普。

為 table view 添加編輯按鈕
  1. 打開 MealTableViewController.swift昨稼。

  2. 在 MealTableViewController.swift 中,找到 viewDidLoad() 方法寻行。

     override func viewDidLoad() {
         super.viewDidLoad()
         
         // Load the sample data.
         loadSampleMeals()
     }
    
  3. 在 super.viewDidLoad() 行的下面拌蜘,添加下面這行代碼:

     // Use the edit button item provided by the table view controller.
     navigationItem.leftBarButtonItem = editButtonItem()
    

    創(chuàng)建了一個(gè)特別的 bar button item 內(nèi)置具有編輯功能简卧。之后添加這個(gè)按鈕到食物場(chǎng)景導(dǎo)航欄的左邊烤芦。

viewDidLoad() 方法應(yīng)該像這樣:

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Use the edit button item provided by the table view controller.
        navigationItem.leftBarButtonItem = editButtonItem()
        
        // Load the sample data.
        loadSampleMeals()
    }

檢驗(yàn):運(yùn)行 app构罗。注意在 table view 導(dǎo)航欄的左邊有個(gè)編輯按鈕绰播。如果點(diǎn)擊編輯按鈕,table view 變成編輯模式-但是你還是沒法刪除單元格链蕊,因?yàn)槟銢]有實(shí)現(xiàn)編輯操作滔韵。

為了執(zhí)行在 table view 的編輯操作陪蜻,你需要實(shí)現(xiàn)其中一個(gè)代理方法贱鼻,tableView(_:commitEditingStyle:forRowAtIndexPath:)。這個(gè)代理方法負(fù)責(zé)在編輯模式時(shí)管理表格行随闽。

你也需要取消 tableView(_:canEditRowAtIndexPath:) 的注釋來支持編輯。

刪除一份食物
  1. 在 MealTableViewController.swift 中肝谭,找到并取消 tableView(_:commitEditingStyle:forRowAtIndexPath:) 的注釋掘宪。(為了取消這個(gè)方法的注釋,移除它周圍的 /* 和 */ 字符攘烛。)

    當(dāng)你做了這些魏滚,模板默認(rèn)實(shí)現(xiàn)如下:

     // Override to support editing the table view.
     override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
         if editingStyle == .Delete {
             // Delete the row from the data source
             tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
         } else if editingStyle == .Insert {
             // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
         }
     }
    
  2. // Delete the row from the data source 這行注釋的下面,添加下面這行代碼:

     meals.removeAtIndex(indexPath.row)
    
  3. MealTableViewController.swift 中坟漱,找到并取消 tableView(_:canEditRowAtIndexPath:) 方法的注釋鼠次。

    做完后,模板默認(rèn)實(shí)現(xiàn)如下:

     // Override to support conditional editing of the table view.
     override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
         // Return false if you do not want the specified item to be editable.
         return true
     }
    

tableView(_:commitEditingStyle:forRowAtIndexPath:) 方法應(yīng)該像這樣:

    // Override to support editing the table view.
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            // Delete the row from the data source
            meals.removeAtIndex(indexPath.row)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
        } else if editingStyle == .Insert {
            // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
        }
    }

檢驗(yàn):運(yùn)行 app须眷。如果點(diǎn)擊編輯按鈕,table view 變成編輯模式沟突』牛可以選擇一個(gè)單元格通過點(diǎn)擊左邊的指示器來刪除,然后通過按單元格的 Delete 按鈕確認(rèn)刪除它惠拭±┤埃或者,向左清掃一個(gè)單元格來快速打開 Delete 按鈕职辅;這是 table view 內(nèi)置的功能棒呛。當(dāng)你點(diǎn)擊單元格刪除按鈕,它就從列表中刪除了域携。

[圖片上傳失敗...(image-670155-1608214610979)]

注意

為了看到本課的完整的示例項(xiàng)目簇秒,下載文件并在 Xcode 中查看它。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秀鞭,一起剝皮案震驚了整個(gè)濱河市趋观,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锋边,老刑警劉巖皱坛,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異豆巨,居然都是意外死亡剩辟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贩猎,“玉大人熊户,你說我怎么就攤上這事∪谂罚” “怎么了敏弃?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)噪馏。 經(jīng)常有香客問我,道長(zhǎng)绿饵,這世上最難降的妖魔是什么欠肾? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮拟赊,結(jié)果婚禮上刺桃,老公的妹妹穿的比我還像新娘。我一直安慰自己吸祟,他們只是感情好瑟慈,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屋匕,像睡著了一般葛碧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上过吻,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天进泼,我揣著相機(jī)與錄音,去河邊找鬼纤虽。 笑死乳绕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逼纸。 我是一名探鬼主播洋措,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼杰刽!你這毒婦竟也來了菠发?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤专缠,失蹤者是張志新(化名)和其女友劉穎雷酪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涝婉,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哥力,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吩跋。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寞射,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锌钮,到底是詐尸還是另有隱情桥温,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布梁丘,位于F島的核電站侵浸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏氛谜。R本人自食惡果不足惜掏觉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望值漫。 院中可真熱鬧澳腹,春花似錦、人聲如沸杨何。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)危虱。三九已至羊娃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間槽地,已是汗流浹背迁沫。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捌蚊,地道東北人集畅。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像缅糟,于是被迫代替她去往敵國(guó)和親挺智。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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