iOS 開(kāi)發(fā) - Swift 全面系統(tǒng)的學(xué)習(xí)(持續(xù)更新...)

最近項(xiàng)目不算緊,于是就學(xué)了學(xué) Swift ,看了一大神寫的項(xiàng)目https://github.com/hrscy/DanTang,很受益,感謝開(kāi)源!另外自己也寫了一些基礎(chǔ)代碼,分享出來(lái),第一是希望得到同行前輩的指導(dǎo),第二是希望對(duì)需要的朋友有所幫助。

先分享一些學(xué)習(xí)資料:





練習(xí)的 demo 地址: https://github.com/liuzhongning/NNMintFurniture

  • 主要包括以下功能:
    • 多頁(yè)面滑動(dòng)視圖(分頁(yè)控制器)
    • 圖片輪播
    • 導(dǎo)航欄漸變
    • 瀑布流練習(xí)
    • UIScrollView 練習(xí)
    • 照相功能,更換頭像
    • 二維碼掃描及識(shí)別
    • 隨機(jī)圖片驗(yàn)證碼封裝
    • 圓形輸入框封裝
    • 第三方庫(kù) SnapKit 用法
    • ............




練習(xí) demo 的簡(jiǎn)單介紹,前方高能預(yù)警,大量圖片請(qǐng)注意手機(jī)流量!

一、多頁(yè)面滑動(dòng)視圖(分頁(yè)控制器)

多頁(yè)面滑動(dòng)視圖
  • 核心代碼
    // MARK: 點(diǎn)擊了標(biāo)簽欄
    func titlesClick(button: UIButton) {
        selectedButton!.isEnabled = true
        selectedButton!.setTitleColor(UIColor.gray, for: .normal)
        button.isEnabled = false
        selectedButton = button
        selectedButton?.setTitleColor(UIColor.red, for: .normal)
        
        var offset = contentView!.contentOffset
        offset.x = CGFloat(button.tag) * (contentView?.frame.size.width)!
        contentView!.setContentOffset(offset, animated: true)
    }
    
    // MARK: 點(diǎn)擊了右邊搜索框
    func rightBarButtonClick() {
        navigationController?.pushViewController(NNSearchController(), animated: true)
    }
    
    // MARK: 點(diǎn)擊了箭頭
    func arrowButtonClick(button: UIButton) {
        UIView.animate(withDuration: 0.25) {
            button.imageView?.transform = button.imageView!.transform.rotated(by: CGFloat(Double.pi))
        }
    }
    
    // MARK: - UIScrollViewDelegate 代理
    // MARK: scrollViewDidEndScrollingAnimation
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        let index = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
        // 取出子控制器
        let vc = childViewControllers[index]
        vc.view.frame.origin.x = scrollView.contentOffset.x
        vc.view.frame.origin.y = 0
        // 設(shè)置控制器的 view 的 height 值為整個(gè)屏幕的高度
        vc.view.frame.size.height = scrollView.frame.size.height
        scrollView.addSubview(vc.view)
    }
    
    // MARK: scrollViewDidEndDecelerating
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        scrollViewDidEndScrollingAnimation(scrollView)
        // 當(dāng)前索引
        let index = Int(scrollView.contentOffset.x / scrollView.frame.size.width)
        // 點(diǎn)擊 Button
        let button = titlesView.subviews[index] as! UIButton
        titlesClick(button: button)
    }

二、圖片輪播

圖片輪播
  • 核心代碼:

輪播圖的封裝

    // MARK: - 懶加載輪播視圖
    private lazy var shufflingFigureView : NNShufflingFigureView = {
        let frame = CGRect(x: 0, y: 0, width: NNScreenWidth, height: 180)
        let imageView = ["shuffling1", "shuffling2", "shuffling3", "shuffling4"]
        let shufflingFigureView = NNShufflingFigureView(frame: frame, images: imageView as NSArray, autoPlay: true, delay: 3, isFromNet: false)
        shufflingFigureView.delegate = self
        return shufflingFigureView
    }()

通過(guò)代理處理圖片的點(diǎn)擊事件

// MARK: - 輪播代理方法,處理輪播圖的點(diǎn)擊事件
extension NNItemTableViewController: NNShufflingFigureViewDelegate {
    func addShufflingFigureView(addShufflingFigureView: NNShufflingFigureView, iconClick index: NSInteger) {
        print(index)
    }
}

三、導(dǎo)航欄漸變

導(dǎo)航欄漸變
  • 核心代碼

頁(yè)面滾動(dòng)時(shí)調(diào)用

// MARK: - UIScrollViewDelegate 滾動(dòng)頁(yè)面時(shí)調(diào)用
extension NNItemTableViewController {
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if type == tableViewType.haveHeader {
            return
        }
        currentPostion = scrollView.contentOffset.y
        if currentPostion > 0 {
            if currentPostion - lastPosition >= 0 {
                if topBool {
                    topBool = false
                    bottomBool = true
                    stopPosition = currentPostion + 64
                }
                lastPosition = currentPostion
                navigationController?.navigationBar.alpha = 1 - currentPostion / 500
            } else {
                if bottomBool {
                    bottomBool = false
                    topBool = true
                    stopPosition = currentPostion + 64
                }
                lastPosition = currentPostion
                navigationController?.navigationBar.alpha = (stopPosition - currentPostion) / 200
            }
        }
    }
}

四、瀑布流練習(xí)

瀑布流練習(xí)
  • 核心代碼

基礎(chǔ)設(shè)置

        // 布局
        let layout = NNItemCollectionViewFlowLayout()
        // 創(chuàng)建collectionView
        let collectionView = UICollectionView.init(frame: view.bounds, collectionViewLayout: layout)
        view.addSubview(collectionView)
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.backgroundColor = UIColor.white
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: NNItemCollectionViewControllerID)

自定義 UICollectionViewFlowLayout

    // MARK: - 更新布局
    override func prepare() {
        super.prepare()
        // 清除所有的布局屬性
        attrsArray.removeAll()
        columnHeightsAry.removeAll()
        
        for _ in 0 ..< columnCountDefault {
            columnHeightsAry.append(edgeInsetsDefault.top)
        }
        
        let sections : Int = (collectionView?.numberOfSections)!
        for num in 0 ..< sections {
            let count : Int = (collectionView?.numberOfItems(inSection: num))!
            for i in 0 ..< count {
                let indexpath : NSIndexPath = NSIndexPath.init(item: i, section: num)
                let attrs = layoutAttributesForItem(at: indexpath as IndexPath)!
                attrsArray.append(attrs)
            }
        }
    }

    // MARK: - cell 對(duì)應(yīng)的布局屬性
    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        
        let attrs = UICollectionViewLayoutAttributes.init(forCellWith: indexPath)
        let collectionWidth = collectionView?.frame.size.width
        // 獲得所有 item 的寬度
        let itemW = (collectionWidth! - edgeInsetsDefault.left - edgeInsetsDefault.right - CGFloat(columnCountDefault-1) * columnMargin) / CGFloat(columnCountDefault)
        let itemH = 50 + arc4random_uniform(100)
        
        // 找出高度最短那一列
        var dextColum : Int = 0
        var minH = columnHeightsAry[0]
        for i in 1 ..< columnCountDefault{
            // 取出第 i 列的高度
            let columnH = columnHeightsAry[i]
            
            if minH > columnH {
                minH = columnH
                dextColum = i
            }
        }
        
        let x = edgeInsetsDefault.left + CGFloat(dextColum) * (itemW + columnMargin)
        var y = minH
        if y != edgeInsetsDefault.top{
            y = y + itemMargin
        }
        attrs.frame = CGRect(x: x, y: y, width: itemW, height: CGFloat(itemH))
        // 更新最短那列高度
        columnHeightsAry[dextColum] = attrs.frame.maxY
        return attrs
    }

五、UIScrollView 練習(xí)

UIScrollView 練習(xí)
  • 核心代碼
    // MARK: - 放大縮小
    // MARK: 放大
    func amplificationBtnClick() {
        var zoomScale = scrollView.zoomScale // 當(dāng)前縮放
        zoomScale += 0.1
        if zoomScale >= scrollView.maximumZoomScale {
            return
        }
        self.scrollView.setZoomScale(zoomScale, animated: true)
    }
    
    // MARK: 縮小
    func narrowDownBtnClick() {
        var zoomScale = scrollView.zoomScale // 當(dāng)前縮放
        zoomScale -= 0.1
        if zoomScale <= scrollView.minimumZoomScale {
            return
        }
        self.scrollView.setZoomScale(zoomScale, animated: true)
    }

// MARK: - NNItemBtnViewDelegate 上下左右點(diǎn)擊代理
extension NNItemScrollView {
    // MARK: 向左
    func leftBtnClickDelegate() {
        var point = self.scrollView.contentOffset
        point.x += 100
        point.x = point.x >= self.scrollView.contentSize.width ? 0 : point.x
        scrollView.setContentOffset(point, animated: true)
    }
    
    // MARK: 向右
    func rightBtnClickDelegate() {
        var point = self.scrollView.contentOffset
        point.x -= 100
        point.x = point.x <= -NNScreenWidth ? 0 : point.x
        scrollView.setContentOffset(point, animated: true)
    }
    
    // MARK: 向上
    func topBtnClickDelegate() {
        var point = self.scrollView.contentOffset
        point.y += 50
        point.y = point.y >= self.scrollView.contentSize.height ? 0 : point.y
        scrollView.setContentOffset(point, animated: true)
    }
    
    // MARK: 向下
    func bottomBtnClickDelegate() {
        var point = self.scrollView.contentOffset
        point.y -= 50
        point.y = point.y <= -NNScreenHeight ? 0 : point.y
        scrollView.setContentOffset(point, animated: true)
    }
}

六、照相功能,更換頭像(建議用真機(jī))

照相功能,更換頭像
  • 核心代碼
// MARK: - 點(diǎn)擊頭像按鈕,更換頭像
    func changePicture() {
        let alertcontroller = UIAlertController(title: "請(qǐng)選擇相片", message: nil, preferredStyle: .actionSheet)
        let alertaction = UIAlertAction(title: "從相冊(cè)選取", style: .destructive) { (action) in
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = .photoLibrary
            imagePicker.allowsEditing = true
            self.present(imagePicker, animated: true, completion: nil)
        }
        
        let alertaction2 = UIAlertAction(title: "拍照", style: .destructive) { (action) in
            if (!UIImagePickerController.isSourceTypeAvailable(.camera)) {
                print("設(shè)備不支持相機(jī)")
                return
            }
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = .camera
            imagePicker.allowsEditing = true
            self.present(imagePicker, animated: true, completion: nil)
        }
        
        let alertAction3 = UIAlertAction(title: "取消", style: .cancel) { (action) in
            print("取消")
        }
        
        alertcontroller.addAction(alertaction)
        alertcontroller.addAction(alertaction2)
        alertcontroller.addAction(alertAction3)
        present(alertcontroller, animated: true, completion: nil)
    }
    
    // MARK: - UIImagePickerControllerDelegate
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        imageView.image = image
        self.dismiss(animated: true, completion: nil)
    }

七、二維碼掃描及識(shí)別(建議用真機(jī))

二維碼掃描及識(shí)別
  • 核心代碼
// MARK: - 掃描設(shè)備設(shè)置
    func setupScanSession() {
        do {
            // 設(shè)置捕捉設(shè)備
            let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
            // 設(shè)置設(shè)備輸入輸出
            let input = try AVCaptureDeviceInput(device: device)
            let output = AVCaptureMetadataOutput()
            output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            
            // 設(shè)置會(huì)話
            let  scanSession = AVCaptureSession()
            scanSession.canSetSessionPreset(AVCaptureSessionPresetHigh)
            
            if scanSession.canAddInput(input) {
                scanSession.addInput(input)
            }
            
            if scanSession.canAddOutput(output) {
                scanSession.addOutput(output)
            }
            
            // 設(shè)置掃描類型(二維碼和條形碼)
            output.metadataObjectTypes = [
                AVMetadataObjectTypeQRCode,
                AVMetadataObjectTypeCode39Code,
                AVMetadataObjectTypeCode128Code,
                AVMetadataObjectTypeCode39Mod43Code,
                AVMetadataObjectTypeEAN13Code,
                AVMetadataObjectTypeEAN8Code,
                AVMetadataObjectTypeCode93Code]
            
            // 預(yù)覽圖層
            let scanPreviewLayer = AVCaptureVideoPreviewLayer(session:scanSession)
            scanPreviewLayer!.videoGravity = AVLayerVideoGravityResizeAspectFill
            scanPreviewLayer!.frame = view.layer.bounds
            
            view.layer.insertSublayer(scanPreviewLayer!, at: 0)
            
            // 設(shè)置掃描區(qū)域
            NotificationCenter.default.addObserver(forName: NSNotification.Name.AVCaptureInputPortFormatDescriptionDidChange, object: nil, queue: nil, using: { (noti) in
                output.rectOfInterest = (scanPreviewLayer?.metadataOutputRectOfInterest(for:self.scanImageView.frame))!
            })
            // 保存會(huì)話
            self.scanSession = scanSession
            
        } catch {
            // 攝像頭不可用
            return
        }
    }

掃描完成后調(diào)用

// MARK: - AVCaptureMetadataOutputObjectsDelegate 掃描捕捉完成
extension NNScanCodeController : AVCaptureMetadataOutputObjectsDelegate {
    func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {
        // 停止掃描
        scanLine.layer.removeAllAnimations()
        scanSession!.stopRunning()
        
        // 掃完完成
        if metadataObjects.count > 0 {
            if let resultObj = metadataObjects.first as? AVMetadataMachineReadableCodeObject {
                print(resultObj.stringValue)
                scanResult.text = "掃描結(jié)果:" + resultObj.stringValue
            }
        }
    }
}

識(shí)別驗(yàn)證碼,從相冊(cè)中選擇

// MARK: - UIImagePickerControllerDelegate, UINavigationControllerDelegate
extension NNScanCodeController : UIImagePickerControllerDelegate , UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        
        // 判斷是否能取到圖片
        guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
            return
        }
        // 轉(zhuǎn)成ciimage
        guard let ciimage = CIImage(image: image) else {
            return
        }
        // 從選中的圖片中讀取二維碼
        // 創(chuàng)建探測(cè)器
        let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy : CIDetectorAccuracyLow])
        let resoult = (detector?.features(in: ciimage))!
        scanResult.text = "無(wú)法識(shí)別"
        for result in resoult {
            guard (result as! CIQRCodeFeature).messageString != nil else {
                return
            }
            
            scanResult.text = "掃描結(jié)果:" + (result as! CIQRCodeFeature).messageString!
        }
        picker.dismiss(animated: true, completion: nil)
    }
}

八、隨機(jī)圖片驗(yàn)證碼封裝

隨機(jī)圖片驗(yàn)證碼封裝
  • 核心代碼
    // MARK: - 繪制圖形驗(yàn)證碼
    override func draw(_ rect: CGRect) {
        if charString.isEmpty {
            return;
        }
        
        let textString:String = charString
        let charSize = textString.substring(to: textString.startIndex).size(attributes: [NSFontAttributeName : UIFont.systemFont(ofSize: 14)])
        let width = rect.size.width / CGFloat(charCount) - charSize.width - 15;
        let hight = rect.size.height - charSize.height;
        var point: CGPoint
        
        var pointX: CGFloat
        var pointY: CGFloat
        for i in 0..<textString.characters.count {
            let char = CGFloat(i)
            pointX = (CGFloat)(arc4random() % UInt32(Float(width))) + rect.size.width / (CGFloat)(textString.characters.count) * char
            pointY = (CGFloat)(arc4random() % UInt32(Float(hight)))
            point = CGPoint(x: pointX, y: pointY)
            let charStr = textString[textString.index(textString.startIndex, offsetBy:i)]
            let string = String(charStr)
            string.draw(at: point,withAttributes:([NSFontAttributeName : UIFont.systemFont(ofSize: 14)]))
        }
        drawLine(rect)
    }
    
    // MARK: - 繪制干擾線
    func drawLine(_ rect: CGRect) {
        let context = UIGraphicsGetCurrentContext()
        context!.setLineWidth(1.0)
        var pointX = 0.0
        var pointY = 0.0
        for _ in 0..<lineCount {
            context!.setStrokeColor(randomColor().cgColor)
            pointX = Double(arc4random() % UInt32(Float(rect.size.width)))
            pointY = Double(arc4random() % UInt32(Float(rect.size.height)))
            context?.move(to: CGPoint(x: pointX, y: pointY))
            pointX = Double(CGFloat(arc4random() % UInt32(Float(rect.size.width))))
            pointY = Double(CGFloat(arc4random() % UInt32(Float(rect.size.height))))
            context?.addLine(to: CGPoint(x: pointX, y: pointY))
            context!.strokePath()
        }
    }

OC版本:iOS開(kāi)發(fā) - 隨機(jī)圖片驗(yàn)證碼封裝-http://www.lxweimin.com/p/936d2e06fd26

九、圓形輸入框封裝

圓形輸入框封裝
  • 核心代碼
    // MARK: - 監(jiān)聽(tīng)文本輸入 核心操作
    func textFieldDidChange(_ textField: UITextField) {
        let i = textField.text?.characters.count
        if i! > labelCount {
            return
        }
        if i == 0 {
            ((labelArr.object(at: 0)) as! UILabel).text = ""
            ((labelArr.object(at: 0)) as! UILabel).layer.borderColor = defaultColor.cgColor
        } else {
            ((labelArr.object(at: (i! - 1))) as! UILabel).text = (textField.text! as NSString).substring(with: NSMakeRange(i! - 1, 1))
            ((labelArr.object(at: (i! - 1))) as! UILabel).layer.borderColor = changedColor.cgColor
            ((labelArr.object(at: (i! - 1))) as! UILabel).textColor = changedColor
            if labelCount > i! {
                ((labelArr.object(at: (i!))) as! UILabel).text = ""
                ((labelArr.object(at: (i!))) as! UILabel).layer.borderColor = defaultColor.cgColor
            }
        }
    }

    // MARK: - setupUI
    func setupUI() {
        setupTextField()
        var labelX = CGFloat()
        let labelY : CGFloat = 0.0
        let labelWidth = self.width / CGFloat(labelCount)
        let sideLength = labelWidth < self.height ? labelWidth : self.height
        
        for i in 0..<labelCount {
            if i == 0 {
                labelX = 0
            } else {
                labelX = CGFloat(i) * (sideLength + labelDistance)
            }
            let label = UILabel(frame: CGRect(x: labelX, y: labelY, width: sideLength, height: sideLength))
            self.addSubview(label)
            label.textAlignment = NSTextAlignment.center
            label.layer.borderColor = UIColor.black.cgColor
            label.layer.borderWidth = 1.0
            label.layer.cornerRadius = sideLength / 2.0
            labelArr.add(label)
        }
    }

    // MARK: - UITextFieldDelegate
    // MARK: 監(jiān)聽(tīng)輸入框
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // 允許刪除
        if (string.characters.count == 0) {
            return true
        } else if (textField.text?.characters.count)! >= labelCount {
            return false
        } else {
            return true
        }
    }
    // MARK: 回車收起鍵盤
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return false
    }

OC版本:iOS開(kāi)發(fā) - 圓形驗(yàn)證碼(或密碼)輸入框的封裝-http://www.lxweimin.com/p/fce6bd4038eb

十、第三方庫(kù) SnapKit 用法

第三方庫(kù) SnapKit 用法
  • 示例代碼
    func addRedView() {
        redView.backgroundColor = UIColor.red
        view.addSubview(redView)
        
        // redView 距離父視圖四條邊的距離都是 50
        redView.snp.makeConstraints { (make) in
            make.edges.equalTo(view).inset(50)
        }
    }
    
    func addBlueView() {
        blueView.backgroundColor = UIColor.blue
        view.addSubview(blueView)
        
        // blueView 左邊距離父視圖為 0;上邊距離父視圖為 0;size 是(50,50)
        blueView.snp.makeConstraints { (make) in
            make.left.equalTo(0)
            make.top.equalTo(0)
            make.size.equalTo(CGSize(width: 50, height: 50))
        }
    }
    
    func addBlackView() {
        blackView.backgroundColor = UIColor.black
        view.addSubview(blackView)
        
        // blackView 左邊和 redView 的右邊距離為 0;大小與 blueView 相同;且與 blueView 上對(duì)齊
        blackView.snp.makeConstraints { (make) in
            make.left.equalTo(redView.snp.right)
            make.size.equalTo(blueView)
            make.top.equalTo(blueView)
        }
    }
    
    func addCyanView() {
        cyanView.backgroundColor = UIColor.cyan
        view.addSubview(cyanView)
        
        // cyanView 與 blueView 左對(duì)齊;cyanView 的頂部距離 redView 的底部 10;cyanView 的高是40;cyanView 與 blueView 等寬
        cyanView.snp.makeConstraints { (make) in
            make.trailing.equalTo(blueView)
            make.top.equalTo(redView.snp.bottom).offset(10)
            make.height.equalTo(40)
            make.width.equalTo(blueView)
        }
    }
    
    func addYellowView() {
        yellowView.backgroundColor = UIColor.yellow
        view.addSubview(yellowView)
        
        // yellowView 頂部與 redView 的底部對(duì)齊;yellowView 與 blackView 左對(duì)齊;yellowView 與 blueView 相同大小
        yellowView.snp.makeConstraints { (make) in
            make.top.equalTo(redView.snp.bottom)
            make.trailing.equalTo(blackView)
            make.size.equalTo(blueView)
        }
    }
    
    func addWhiteView() {
        whiteView.backgroundColor = UIColor.white
        redView.addSubview(whiteView)
        
        // whiteView 的父視圖是 redView,距離父視圖四條邊的距離分別是(30,10,30,10)
        
        whiteView.snp.makeConstraints { (make) in
            // 第一種方式
            make.edges.equalTo(redView).inset(UIEdgeInsets(top: 30, left: 10, bottom: 30, right: 10))
            // 第二種方式
//            make.top.equalTo(redView).offset(30)
//            make.left.equalTo(redView).offset(10)
//            make.bottom.equalTo(redView).offset(-30)
//            make.right.equalTo(redView).offset(-10)
            // 第三種方式
//            make.top.left.bottom.right.equalTo(redView).inset(UIEdgeInsets(top: 30, left: 10, bottom: 30, right: 10))
        }
    }




詳情代碼,請(qǐng)移步到 https://github.com/liuzhongning/NNMintFurniture 中查看,如有疑問(wèn)或有建議的地方,歡迎討論。另外代碼中有一個(gè)名為 guide.swift 的類,簡(jiǎn)單標(biāo)出了代碼的結(jié)構(gòu),更方便閱讀。
會(huì)持續(xù)更新......
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,555評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,900評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,629評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,976評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評(píng)論 3 448
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,139評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,411評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,641評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,820評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,233評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,567評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,362評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,604評(píng)論 2 380

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

  • 是絮叨,哪處酒家飯菜沒(méi)我做的好。 嘴不停手不亂,洗洗刷刷和翻翻炒炒。 柴米油鹽,鍋碗瓢盆,砧板火灶。 胭脂味飄不進(jìn)...
    木土有阿杜閱讀 226評(píng)論 0 1
  • 古人曰:“見(jiàn)字如見(jiàn)人。”而我想說(shuō),見(jiàn)字如聞其心。我不知道別人怎么樣,但我知道我必須心非常非常地靜時(shí),我的字才能看。...
    無(wú)心悠悠然閱讀 651評(píng)論 6 1
  • 午夜的鐘聲敲響了,然寶五周歲了。在不經(jīng)意間我們共同度過(guò)了5年。歲月讓你從出生時(shí)50CM到現(xiàn)在已經(jīng)懂得美丑好壞了,而...
    珊珊手心閱讀 245評(píng)論 0 0
  • 我有個(gè)哥哥,盡管我基本上沒(méi)有叫過(guò)他哥哥,因?yàn)樗槐任掖?個(gè)月,我們來(lái)自一個(gè)族系,本家那種,從小在一個(gè)班級(jí),直到初中...
    7f8903e23e9e閱讀 156評(píng)論 0 0