我寫一個IOS日歷應(yīng)用的過程-swift

需求

在項目中要用到一個日歷控件,它需要支持單選粗恢、多選、節(jié)選(選擇首尾)日期的功能欧瘪,在網(wǎng)上找了一下眷射,我不喜歡項目中出現(xiàn)OC,而swift代碼里沒找到太合適的控件佛掖,就琢磨著自己寫一個妖碉。

地址

https://github.com/xiaohepan/Calendar.git

結(jié)構(gòu)

我想使用collectionView或者tableView來實現(xiàn)我的日歷控件,現(xiàn)在已經(jīng)寫好了使用collectionView實現(xiàn)的控件芥被,就以collectionView來講這個過程欧宜。

  1. 以一個月為一個section,一天為一個cell拴魄,而collectionView的sectionHeader正好可以作為一個月的標題冗茸。在設(shè)置了startDate和endDate之后,要計算出有幾個月羹铅,每個月有多少天蚀狰。如果能夠計算出這兩個值collectionView的dataSource 要實現(xiàn)的兩個方法就完成了:
numberOfSectionsInCollectionView(collectionView:     UICollectionView) -> Int愉昆;
collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
  1. 接下來就要獲得每天的信息职员,比如是否可以選擇(selectable),是否已經(jīng)選中(selected)跛溉,是否是今天(isToday)焊切,是否在本月(isInMonth,因為要按星期排芳室,所以在月初月末要用臨近月份占坑)专肪。所以我定義了一個結(jié)構(gòu)體來表達這些信息。
public struct DayStateOptions:OptionSetType{
    
    public var rawValue:UInt
    
    public init(rawValue: UInt){
        self.rawValue = rawValue
    }
    public static var NotThisMonth:DayStateOptions{
        return DayStateOptions(rawValue: 1<<0)
    }
    public static var Today:DayStateOptions{
        return DayStateOptions(rawValue: 1<<1)
    }
    public static var UnSelectable:DayStateOptions{
        return DayStateOptions(rawValue: 1<<2)
    }
    public static var Selected:DayStateOptions{
        return DayStateOptions(rawValue: 1<<3)
    }
}
  1. 再下來堪侯,就要考慮不可選嚎尤、單選、多選伍宦、節(jié)選(選擇首尾)這四種選擇模式芽死。collectionView 有allowsSelection、allowsMultipleSelection兩個屬性次洼,不可選的時候allowsSelection = false关贵,單選的時候 allowsSelection = true ,allowsMultipleSelection = false卖毁,多選和節(jié)選的時候 allowsSelection = true揖曾,allowsMultipleSelection = true。節(jié)選的情況要我們自己做處理。我定義了一個枚舉來表示這四種模式
public enum SelectionType:Int{
    case None = 0,Single,Mutable,Section
}

具體實現(xiàn)

我把這些計算放在了一個CalenadrDataSource類里炭剪,先看他的屬性
//默認的開始日期

  1. public static let defaultFirstDate = NSDate(timeIntervalSince1970: -28800)
    //默認的結(jié)束日期
  2. public static let defaultLastDate = NSDate(timeIntervalSince1970:2145801599)
    //保存用戶設(shè)置的開始日期
  3. private var firstDate:NSDate!
    //保存用戶設(shè)置的結(jié)束日期
  4. private var lastDate:NSDate!
    //用戶設(shè)置的開始日期的月初那一秒
  5. private var firstDateMonthBegainDate:NSDate!
    //用戶設(shè)置的結(jié)束日期的月末那一秒
  6. private var lastDateMonthEndDate:NSDate!
    //日歷類
  7. lazy var calendar:NSCalendar
    //當天所在的NSIndexPath
  8. private var todayIndex:NSIndexPath?
    //選中的日子所在的位置的數(shù)組练链,單選保持0-1個值,多選 0-N個值,節(jié)選 0-2個值
  9. private var selectedDates = NSIndexPath
    //格式化
  10. public let formatter:NSDateFormatter
    //選擇模式
  11. public var selectionType:SelectionType = .None
    //日歷開始的日期念祭,計算屬性
  12. public var startDate:NSDate
    //日歷結(jié)束的日期,計算屬性
  13. public var endDate:NSDate
    //有幾個月
  14. public var monthCount:Int

只有calendar,formatter,selectionType,startDate,endDate是公開的,startDate,endDate是計算屬性,根據(jù)這兩個值,計算出firstDate,lastDate,firstDateMonthBegainDate,lastDateMonthEndDate,todayIndex,monthCount兑宇。

再看CalenadrDataSource的構(gòu)造方法

//使用默認的開始和結(jié)束時間
    public convenience init(){
        self.init(startDate:CalenadrDataSource.defaultFirstDate,endDate:CalenadrDataSource.defaultLastDate)
    }
    //使用自定義的開始和結(jié)束時間
    public init(startDate:NSDate,endDate:NSDate){
        let result = startDate.compare(endDate)
        if result == .OrderedDescending {
            fatalError("startDate must smaller than endDate")
        }
        self.formatter = NSDateFormatter()
        self.startDate = startDate
        self.endDate = endDate
        formatter.dateFormat = "yyyy年MM月"
    }

再看其它業(yè)務(wù)方法:

    //多少年
    public func yearCount() -> Int
    {
    }
    //一星期多少天
    public func daysInWeek() -> Int{
        return calendar.maximumRangeOfUnit(.Weekday).length
    }
    //一個月多少天
    public func daysInMonth(monthIndex:Int) -> Int{
        return weeksInMonth(monthIndex) * daysInWeek()
    }
    //每天的信息
    public func dayState(indexPath:NSIndexPath) -> (NSDate,DayStateOptions){
    }
   //格式化日期
    public func StringDayFromDate(date:NSDate) -> String{
        return String(self.calendar.component(.Day, fromDate: date))
    }
   //格式化日期
    public func StringDateFromDate(date:NSDate) -> String{
        return formatter.stringFromDate(date)
    }
    //某個section的對應(yīng)月份有幾個星期
    public func weeksInMonth(monthIndex:Int) -> Int{
    }
    //把時時分分秒秒的信息改成0
    private func clampDate(date:NSDate, toComponents unitFlags:NSCalendarUnit) -> NSDate{
    }
    //某個section的對應(yīng)月份開始那天
    private func firstOfMonthForSection(monthIndex:Int) -> NSDate
    {
    }
     //某個section的對應(yīng)月份的信息 目前和firstOfMonthForSection差不多
    public func monthState(monthIndex:Int) -> NSDate
    {
    }
     //某日期所在的section
    func sectionForDate(date:NSDate) -> Int
    {
    }
     //某日期所在的NSIndexPath
    func indexPathForRowAtDate(date:NSDate) -> NSIndexPath
    {
    }
     //選中某天,返回true表示修改了selectedDates粱坤,collectionView需要刷新
    func didSelectItemAtIndexPath(indexPath:NSIndexPath) -> Bool{
    }
   //選中某天隶糕,返回true表示修改了selectedDates,collectionView需要刷新
    func didDeselectItemAtIndexPath(indexPath:NSIndexPath) -> Bool{
    }

有了這個類就能很方便的用collectionView寫出日歷控件了。但現(xiàn)在的實現(xiàn)有些差站玄,還有很多要改進的地方枚驻。希望多指教。完整代碼如下:

public class CalenadrDataSource
{
    
    public static let defaultFirstDate = NSDate(timeIntervalSince1970: -28800)
    public static let defaultLastDate = NSDate(timeIntervalSince1970:2145801599)
    //保存用戶設(shè)置的開始日期
    private var firstDate:NSDate!
    //保存用戶設(shè)置的結(jié)束日期
    private var lastDate:NSDate!
    //用戶設(shè)置的開始日期的開始那一秒
    private var firstDateMonthBegainDate:NSDate!
    //用戶設(shè)置的結(jié)束日期的結(jié)束那一秒
    private var lastDateMonthEndDate:NSDate!
    
    private lazy var calendar:NSCalendar = {
        //            let calendar =
        return NSCalendar.currentCalendar()
    }()
    
    private var todayIndex:NSIndexPath?
    
    var selectedDates = [NSIndexPath]()
    
    let formatter:NSDateFormatter
    
    var selectionType:SelectionType = .None{
        
        didSet{
            if selectionType == .None{
                selectedDates.removeAll()
                return
            }
            if selectedDates.count < 2 {
                return
            }
            switch (oldValue,selectionType) {
            case (.Mutable,.Single):
                selectedDates = Array(selectedDates.prefix(1))
            case (.Section,.Single):
                selectedDates = Array(selectedDates.prefix(1))
            case (.Mutable,.Section):
                selectedDates = [selectedDates.first!,selectedDates.last!]
            case (.Section,.Mutable):
               sectionToMutable()
            default:
                break
            }
        }
    }
    //日歷開始的日期
    public var startDate:NSDate{
        set{
            if firstDate != nil && newValue.isEqualToDate(firstDate){
                return
            }
            if lastDate != nil{
                let result = newValue.compare(lastDate)
                if result == .OrderedDescending {
                    fatalError("startDate must smaller than endDate")
                }
                
            }
            
            firstDate =  clampDate(newValue, toComponents: [.Year,.Month,.Day])
            firstDateMonthBegainDate =  clampDate(newValue, toComponents: [.Month,.Year])
            if lastDate != nil{
                let today = NSDate()
                let result1 = today.compare(newValue)
                let result2 = today.compare(lastDate)
                if result1 != .OrderedAscending && result2 != .OrderedDescending{
                    todayIndex = indexPathForRowAtDate(today)
                }else{
                    todayIndex = nil
                }
            }
        }
        get{
            return firstDate
        }
    }
    
    //日歷結(jié)束的日期
    public var endDate:NSDate{
        set{
            if lastDate != nil && newValue.isEqualToDate(lastDate){
                return
            }
            if firstDate != nil{
                let result = firstDate.compare(newValue)
                if result == .OrderedDescending {
                    fatalError("startDate must smaller than endDate")
                }
            }
            let components =  self.calendar.components([.Year,.Month,.Day],fromDate:newValue)
            components.hour = 23
            components.minute = 59
            components.second = 59
            lastDate = self.calendar.dateFromComponents(components)
            let firstOfMonth = self.clampDate(newValue, toComponents: [.Month,.Year])
            let offsetComponents = NSDateComponents()
            offsetComponents.month = 1
            let temp = self.calendar.dateByAddingComponents(offsetComponents, toDate: firstOfMonth, options: .WrapComponents)!
            lastDateMonthEndDate = NSDate(timeIntervalSince1970: temp.timeIntervalSince1970 - 1)
            if firstDate != nil{
                let today = NSDate()
                let result1 = today.compare(firstDate)
                let result2 = today.compare(newValue)
                if result1 != .OrderedAscending && result2 != .OrderedDescending{
                    todayIndex = indexPathForRowAtDate(today)
                    todayIndex?.section
                    todayIndex?.row
                }else{
                    todayIndex = nil
                }
            }
        }
        get{
            return lastDate
        }
    }
    
    
    
    
    func sectionToMutable(){
//        let length = self.calendar.components(.Day, fromDate: selectedDates[0], toDate: selectedDates[1], options: NSCalendarOptions(rawValue: 0)).day
//        selectedDates = Array<NSIndexPath>()
//        var date = selectedDates[0]
//        let offset = NSDateComponents()
//        offset.day = 1
//        for _ in 0 ..< length {
//            selectedDates.append(date)
//            date = self.calendar.dateByAddingComponents(offset, toDate: date, options: NSCalendarOptions(rawValue: 0))!
//        }
    }
    
    
    //使用默認的開始和結(jié)束時間
    public convenience init(){
        self.init(startDate:CalenadrDataSource.defaultFirstDate,endDate:CalenadrDataSource.defaultLastDate)
    }
    //使用自定義的開始和結(jié)束時間
    public init(startDate:NSDate,endDate:NSDate){
        let result = startDate.compare(endDate)
        if result == .OrderedDescending {
            fatalError("startDate must smaller than endDate")
        }
        self.formatter = NSDateFormatter()
        self.startDate = startDate
        self.endDate = endDate
        formatter.dateFormat = "yyyy年MM月"
    }
    
    //多少年
    public func yearCount() -> Int
    {
        let startYear = calendar.components(.Year,fromDate: CalenadrDataSource.defaultFirstDate, toDate: firstDateMonthBegainDate,options: .WrapComponents).year
        
        let endYear = calendar.components(.Year,fromDate: CalenadrDataSource.defaultFirstDate, toDate: lastDateMonthEndDate,options: .WrapComponents).year
        
        return endYear - startYear + 1
    }
    
    
    
    //一星期多少天
    public func daysInWeek() -> Int{
        return calendar.maximumRangeOfUnit(.Weekday).length
    }
    
    
    
    //多少月
    public var monthCount:Int{
        get{
            return calendar.components(.Month, fromDate: firstDateMonthBegainDate, toDate: lastDateMonthEndDate, options: .WrapComponents).month + 1
        }
    }
    
    //一個月多少天
    public func daysInMonth(monthIndex:Int) -> Int{
        return weeksInMonth(monthIndex) * daysInWeek()
    }
    //每天的信息
    public func dayState(indexPath:NSIndexPath) -> (NSDate,DayStateOptions){
        var options = DayStateOptions(rawValue:0)
        
        if todayIndex != nil{
            if indexPath.isEqual(todayIndex){
                options = [options,.Today]
            }
        }
        
        let firstOfMonth =  self.firstOfMonthForSection(indexPath.section)
        
        let ordinalityOfFirstDay =  1 - self.calendar.component(.Weekday, fromDate: firstOfMonth) + indexPath.row
        
        if ordinalityOfFirstDay < 0{
            options = [options,.NotThisMonth]
        } else{
            let maxRangeDay =  calendar.rangeOfUnit(.Day, inUnit: .Month, forDate: firstOfMonth).length
            if ordinalityOfFirstDay >= maxRangeDay{
                options = [options,.NotThisMonth]
            }else{
                let count = selectedDates.count
                switch count{
                case 0:
                    break
                case 2:
                    if selectionType == .Section{
                        let a = selectedDates[0].compare(indexPath)
                        NSLog("a = \(a)")
                        if a == .OrderedAscending {
                            let b = indexPath.compare(selectedDates[1])
                              NSLog("b = \(b)")
                            if b != .OrderedDescending{
                                options = [options,.Selected]
                            }
                        }else if a == .OrderedSame{
                             options = [options,.Selected]
                        }
                    }else{
                        fallthrough
                    }
                default:
                    if selectedDates.contains(indexPath){
                        options = [options,.Selected]
                    }
                }
            }
        }
        let  dateComponents = NSDateComponents()
        dateComponents.day = ordinalityOfFirstDay
        let date = self.calendar.dateByAddingComponents(dateComponents, toDate: firstOfMonth, options: NSCalendarOptions(rawValue: 0))!
        return (date,options)

    }

    public func StringDayFromDate(date:NSDate) -> String{
        return String(self.calendar.component(.Day, fromDate: date))
    }
    public func StringDateFromDate(date:NSDate) -> String{
        return formatter.stringFromDate(date)
    }
    
   
    
    //一個月多少星期
    public func weeksInMonth(monthIndex:Int) -> Int{
        let firstOfMonth = self.firstOfMonthForSection(monthIndex)
        let rangeOfWeeks = self.calendar.rangeOfUnit(.WeekOfMonth,inUnit: .Month,forDate: firstOfMonth).length
        return rangeOfWeeks
    }
    
    
    
    private func clampDate(date:NSDate, toComponents unitFlags:NSCalendarUnit) -> NSDate{
        let components = self.calendar.components(unitFlags,fromDate:date)
        return self.calendar.dateFromComponents(components)!
    }
    //一個月開始的時間
    private func firstOfMonthForSection(monthIndex:Int) -> NSDate
    {
        let offset = NSDateComponents()
        offset.month = monthIndex
        return self.calendar.dateByAddingComponents(offset, toDate: firstDateMonthBegainDate, options: NSCalendarOptions(rawValue: 0))!
    }
    
    
    public func monthState(monthIndex:Int) -> NSDate
    {
        let offset = NSDateComponents()
        offset.month = monthIndex
        return self.calendar.dateByAddingComponents(offset, toDate: firstDateMonthBegainDate, options: NSCalendarOptions(rawValue: 0))!
    }
    
    
    func sectionForDate(date:NSDate) -> Int
    {
        return self.calendar.components(.Month,fromDate:self.firstDateMonthBegainDate,toDate:date,options:.WrapComponents).month
    }
    
    func indexPathForRowAtDate(date:NSDate) -> NSIndexPath
    {
        let section = self.sectionForDate(date)
        let firstOfMonth = self.firstOfMonthForSection(section)
        
        let ordinalityOfFirstDay =  1 - self.calendar.component(.Weekday, fromDate: firstOfMonth)
        
        let  dateComponents = NSDateComponents()
        dateComponents.day = ordinalityOfFirstDay
        let startDateInSection = self.calendar.dateByAddingComponents(dateComponents, toDate: firstOfMonth, options: NSCalendarOptions(rawValue: 0))!
        
        let row = self.calendar.components(.Day, fromDate: startDateInSection, toDate: date, options: NSCalendarOptions(rawValue: 0)).day
        return NSIndexPath(forRow:row,inSection:section)
    }
    
    func didSelectItemAtIndexPath(indexPath:NSIndexPath) -> Bool{
        
        if selectedDates.contains(indexPath){
            return false
        }
        switch selectionType {
        case .None:
            return false
        case .Single:
            if selectedDates.count == 0{
                selectedDates.append(indexPath)
            }else{
                selectedDates[0] = indexPath
            }
        case .Mutable:
            selectedDates.append(indexPath)
        case .Section:
            if selectedDates.count == 0{
                selectedDates.append(indexPath)
            }else if selectedDates.count == 1{
                let result = selectedDates[0].compare(indexPath)
                switch result {
                case .OrderedSame:
                    return false
                case .OrderedAscending:
                    selectedDates.append(indexPath)
                case .OrderedDescending:
                   selectedDates.insert(indexPath, atIndex: 0)
                }
            }else{
                selectedDates.removeAll()
                selectedDates.append(indexPath)
            }
        }
        NSLog("didSelectItemAtIndexPath \(selectedDates)")
        return true
    }
    func didDeselectItemAtIndexPath(indexPath:NSIndexPath) -> Bool{
        if let index = selectedDates.indexOf(indexPath){
            selectedDates.removeAtIndex(index)
             NSLog("didDeselectItemAtIndexPath \(selectedDates)")
            return true
        }
        return false
    }
    
}

public struct DayStateOptions:OptionSetType{
    
    public var rawValue:UInt
    
    public init(rawValue: UInt){
        self.rawValue = rawValue
    }
    public static var NotThisMonth:DayStateOptions{
        return DayStateOptions(rawValue: 1<<0)
    }
    public static var Today:DayStateOptions{
        return DayStateOptions(rawValue: 1<<1)
    }
    public static var UnSelectable:DayStateOptions{
        return DayStateOptions(rawValue: 1<<2)
    }
    public static var Selected:DayStateOptions{
        return DayStateOptions(rawValue: 1<<3)
    }
}
public enum SelectionType:Int{
    case None = 0,Single,Mutable,Section
}
class TimeSelectorVC: UICollectionViewController
{
    
    private var  dataSourceManager:CalenadrDataSource
    
    var selectionType:SelectionType = .Section{
        didSet{
            guard oldValue  != selectionType else{
                return
            }
            initSelectionType()
        }
    }
    
    
    required init?(coder aDecoder: NSCoder) {
        dataSourceManager = CalenadrDataSource()
        super.init(coder: aDecoder)
    }
    
    override init(collectionViewLayout layout: UICollectionViewLayout) {
        dataSourceManager = CalenadrDataSource()
        super.init(collectionViewLayout: layout)
    }
    
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        dataSourceManager = CalenadrDataSource()
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        initSelectionType()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
  
    }
    
    func initSelectionType(){
        switch selectionType {
        case .None:
            self.collectionView?.allowsSelection = false
            dataSourceManager.selectionType = .None
        case .Single:
            self.collectionView?.allowsSelection = true
            self.collectionView?.allowsMultipleSelection = false
            dataSourceManager.selectionType = .Single
        case .Mutable:
            self.collectionView?.allowsSelection = true
            self.collectionView?.allowsMultipleSelection = true
            dataSourceManager.selectionType = .Mutable
        case .Section:
            self.collectionView?.allowsSelection = true
            self.collectionView?.allowsMultipleSelection = true
            dataSourceManager.selectionType = .Section
        }

    }
    
    // MARK: UICollectionViewDataSource
    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return dataSourceManager.monthCount
    }


    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return dataSourceManager.daysInMonth(section)
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("DayCell", forIndexPath: indexPath)
        let (date,dayState) = dataSourceManager.dayState(indexPath)
        if let label = cell.viewWithTag(1) as? UILabel
        {
            if dayState.contains(.NotThisMonth)
            {
                label.hidden = true
                cell.backgroundColor = UIColor.whiteColor()
            }else{
                label.hidden = false
                label.text = dataSourceManager.StringDayFromDate(date)
                if dayState.contains(.Selected){
                
                    if dayState.contains(.Today){
                       cell.backgroundColor = UIColor.redColor()
                    }else{
                       cell.backgroundColor = UIColor.blueColor()
                    }
                    label.textColor = UIColor.whiteColor()
                }else{
                    cell.backgroundColor = UIColor.whiteColor()
                    if dayState.contains(.Today){
                        label.textColor = UIColor.redColor()
                    }else{
                        label.textColor = UIColor.blackColor()
                    }
                }
            }
        }
        return cell
    }

    override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
    {
        let cell = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "SectionCell", forIndexPath: indexPath)
        if let label = cell.viewWithTag(1) as? UILabel
        {
            label.text = dataSourceManager.StringDateFromDate(dataSourceManager.monthState(indexPath.section))
        }
        
        return cell
    }
    
    // MARK: UICollectionViewDelegate
    override func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
        let (_,dayState) = dataSourceManager.dayState(indexPath)
        if dayState.contains(.NotThisMonth) || dayState.contains(.UnSelectable){
            return false
        }
        return true
    }

    override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        if dataSourceManager.didSelectItemAtIndexPath(indexPath){
            self.collectionView?.reloadData()
        }
    }
    
    override func collectionView(collectionView: UICollectionView, shouldDeselectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }
    
    override func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
        if dataSourceManager.didDeselectItemAtIndexPath(indexPath){
            self.collectionView?.reloadData()
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末株旷,一起剝皮案震驚了整個濱河市再登,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晾剖,老刑警劉巖锉矢,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異齿尽,居然都是意外死亡沽损,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門循头,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绵估,“玉大人,你說我怎么就攤上這事卡骂」眩” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵全跨,是天一觀的道長缝左。 經(jīng)常有香客問我,道長浓若,這世上最難降的妖魔是什么渺杉? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮七嫌,結(jié)果婚禮上少办,老公的妹妹穿的比我還像新娘。我一直安慰自己诵原,他們只是感情好英妓,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布挽放。 她就那樣靜靜地躺著,像睡著了一般蔓纠。 火紅的嫁衣襯著肌膚如雪辑畦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天腿倚,我揣著相機與錄音纯出,去河邊找鬼。 笑死敷燎,一個胖子當著我的面吹牛暂筝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硬贯,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼焕襟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了饭豹?” 一聲冷哼從身側(cè)響起鸵赖,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拄衰,沒想到半個月后它褪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡翘悉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年茫打,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镐确。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡包吝,死狀恐怖饼煞,靈堂內(nèi)的尸體忽然破棺而出源葫,到底是詐尸還是另有隱情,我是刑警寧澤砖瞧,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布息堂,位于F島的核電站,受9級特大地震影響块促,放射性物質(zhì)發(fā)生泄漏荣堰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一竭翠、第九天 我趴在偏房一處隱蔽的房頂上張望振坚。 院中可真熱鬧,春花似錦斋扰、人聲如沸渡八。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屎鳍。三九已至宏娄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逮壁,已是汗流浹背孵坚。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留窥淆,地道東北人卖宠。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像忧饭,于是被迫代替她去往敵國和親逗堵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

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

  • 因為要結(jié)局swift3.0中引用snapKit的問題,看到一篇介紹Xcode8,swift3變化的文章,覺得很詳細...
    uniapp閱讀 4,414評論 0 12
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理眷昆,服務(wù)發(fā)現(xiàn)蜒秤,斷路器,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • Demo地址 一亚斋、簡介 蘋果官方關(guān)于日歷和提醒簡介 Important:An iOS app linked on ...
    StarHuiDream閱讀 9,182評論 7 11
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法作媚,類相關(guān)的語法,內(nèi)部類的語法帅刊,繼承相關(guān)的語法纸泡,異常的語法,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • 文|傅青巖 全目錄|木棉花樹下的守候 上一節(jié)(31)一鍵優(yōu)化惹的“禍” 上一節(jié)提示赖瞒,程小鹿沖冠一怒為男顏女揭,與洪亮他...
    傅青巖閱讀 478評論 15 28