Jekyll-Admin-Mac 开发纪要-左侧菜单栏

本博客将在 6月底停止在 简书的更新,全新的博客地址请点击前往-> 君赏博客

本文章文字大约 4500字,大概花费 10分钟阅读。本文章设计的图片比较多,流量党慎入!。

本教程属于 制作 Jekyll-Admin-Mac的教程系列,可以关于 君赏博客关注以后教程。

本文章一些知识点,不感兴趣可以提前关闭!

  • Curl下载命令
  • 使用 Xib
  • 使用 Autolayout
  • OSX开发
  • @IBDesignable@IBInspectable
  • draw()
  • 自定义NSView的背景颜色
  • 使用 Xib 加载试图
  • 设置 autoresizingMask属性
  • 修改 NSWindow的最小显示区域
  • 去掉 NSTableView的边框
  • NSTableView使用 View Base试图
  • OSX使用 `font-awesome
  • 如何在 Swift3获取类名字符串
  • 解决 Cocoapods不能使用 IBDeisgnable
  • 面向对象思想

✅为什么要开发 Jekyll-Admin-Mac?

因为接触到使用 Jekyll构建博客十分的方便,但是 Jekyll-Admin里面的功能又差强人意。

如果修改 Jekyll-Admin里面的源码代价是巨大的,不如用自己擅长的语言来写,正好还有自动生成的 API 可以用。

对于 Jekyll-Admin-MacUI我们采用网页的配色即可。

获取 Jekyll-Admin的图标。

经过网络抓包,我们抓取到 Jekyll-Admin的图标是经过连接

../admin/847c038a8202754b465604459e16715d.png来获取的。

我们直接保存到本地,在工程里面使用。

我们新建一个 Mac的工程保存到本地名字叫做- Jekyll-Admin-Mac

我们打开终端 terminal.app

cd /Users/用户名称/Downloads
curl -o jekyll-admin-logo.png ../admin/847c038a8202754b465604459e16715d.png

⚠️这里我们用到了 curl命令,更多的想知道 curl命令可以去谷歌和百度。

设置左侧的 Logo

我们拖拽文件 jekyll-admin-logo.png到工程 Assets.xcassets

左边功能菜单我们设置宽度为 205

我们新建一个 SideMenuView继承 NSView

现在 NSView创建的时候不允许使用 XIB,我们自己新建一个 Xib

名字叫做 SideMenuView.xib

我们设置 SideMenuView的大小为 205x1000。宽度是固定的,但是高度不固定,我们使用自动布局。

最上线显示 Logo的地方大小为 205x75。我们采用 NSImageView。我们采用如下的布局。

  • 左侧和父试图对其
  • 上侧和父试图对其
  • 宽度205
  • 高度75

⚠️我们发现我们的图片是正常的显示出来了,但是背景颜色无法显示。那是因为在 OSX开发和 iOS不太一样。对于正常的 NSView, NSImageView是无法进行设置背景颜色的。

@IBDesignable和@IBInspectable

为了可以自定义背景颜色,我们创建一个继承 NSView的子类 BaseView

@IBDesignable class BaseView: NSView {
}

我们在 BaseView新增一个属性。

@IBInspectable  var backgroundColor:NSColor! = NSColor.white {
    didSet {
        self.needsToDraw(self.bounds)
    }
}

自定义draw()

我们在 func draw(_ dirtyRect: NSRect)方法里面进行填充颜色。

override func draw(_ dirtyRect: NSRect) {
  super.draw(dirtyRect)
  self.backgroundColor.setFill()
  NSRectFill(dirtyRect)
}

关于怎么在 XIB及时预览界面可以参考下面的连接。

在Xcode6中使用IBDesignable创建自定义控件(翻译)

关于如何 NSView自定义背景颜色参考下面的连接

我们设置 NSView为继承与 BaseView 背景颜色试图。我们设置背景颜色为 rgb343434

布局参考之前 NSImageView的布局。

我们把刚才的 NSImageView作为子试图,布局设置下面。

我们拖拽 NSView一个新的试图放置在 Main.storyboard-ViewController-View上面。

我们设置刚才新建的 NSView继承我们新建的类 SideMenuView

使用 Xib 加载试图

到这里,我们新建的 NSView无法正常的显示出来。那是因为我们在 XIB进行初始化的时候走的是方法是

public init?(coder: NSCoder)

并且 SideMenuView这个类不知道从哪里加载试图。关于如何进行加载自定义的 XIB可以参考这一篇文章。

怎么让继承的类直接使用XIB的布局试图

我们新增一个绑定的属性

@IBOutlet weak var view: BaseView!

设置 XibFile's Owner类为 SideMenuView,绑定 view

我们在 SideMenuView类里面新增一个方法,用来加载自定义的试图。

func loadXibView() {
      Bundle.main.loadNibNamed("SideMenuView", owner: self, topLevelObjects: nil)
      self.view.frame = self.bounds
      self.addSubview(self.view)
 }

我们重写 init?(coder: NSCoder)方法。

required init?(coder: NSCoder) {
    super.init(coder: coder)
    self.loadXibView()
}

当我们再次的运行,我们自定义 Xib的界面已经可以出现了。

但是到目前来说我们几乎达到显示 Logo,但是我们的背景颜色设置白色不是我们所希望的,我们设置默认的为透明颜色。

我们还发现我们我们的试图并没有达到我们设置约束的大小。

我们可以点击 Xcode查看试图层次

我们看出SideMenuView试图的 View并没有达到我们随着父试图变化而变化。

设置 autoresizingMask属性

我们设置一下 autoresizingMask属性。关于 autoresizingMask一些用法可以看一下下面的资料。

iOS开发-自动布局之autoresizingMask使用详解(Storyboard&Code)

我们设置高度自适应。

self.view.autoresizingMask = .viewHeightSizable

我们设置 SideMenuViewview的背景为rgb515151,方便我们进行查看。

我的试图已经能随着变化自动改变高度了。

这个时候我们还发现了一个问题,我们的 Window可以压缩宽度最小,这样左边的侧栏已经挡着了。

修改 Window的最小显示区域

我们可以通过下面设置 window的最小值。

这样我们可以让 Window可以保持最小的尺寸是 600x500

我们修改 SideMenuViewview的试图背景颜色为 RGB444444

上面的图可以明显看出来是需要封装控件的,但是封装完毕是试图依次叠加还是使用 NSTableView。试图依次叠加不利于扩展,我们采用 NSTableView

我们拖拽一个 NSTableView的控件放置在 SideMenuView剩余的位置。布局如下。

如图所示的版本还不能达到我们的要求,有了标题,而且多了一个 Column

我们取消显示 Header和设置只有一个 Cloumn

我们发现我们剩下的只有一个 Column的宽度只有 116并不是全屏显示的。

去掉 NSTableView的边框

我们设置宽度为 205

我们现在发现了一个问题,我们本来有205的宽度的。但是我们现在只能设置最大200,并且预览显示是全屏显示了。

我们在 NSTableView的属性里面看到这个。

我们的宽度留3大小。但是就算去掉了3还是只有 203,剩下的 2跑到那里去了。

我们观察到 NSTableView的父试图已经是 203的宽度了,既然这样我们就默认使用 200

可以设置最外层 Border为没有即可。

我们发现我们刚才创建的 NSTableView显示的背景颜色是白色的,我们可以关闭 NSScrollView的绘制背景颜色和设置 NSTableView的背景颜色为透明即可。

虽然系统的 NSButton是符合图片加文字效果的,但是却无法修改文字的颜色。

我们创建一个类继承与 BaseView名字叫做 SideMenuItemView

我们按照上文所描述的方法创建一个 Xib文件。

我们设置 Xib里面的 NSView的宽度为 205,高度为 49。其实我们这个宽度和高度会随着改变的。

我们在最左侧放置一个 NSImageView布局如下。

我们在 NSImageView的右侧放置一个 NSTextFiledLabel,布局如下。

我们设置右侧 Label的字体颜色为 ebdac1,字体大小为 17px

我们利用 Xib创建下面的关联属性。

@IBOutlet weak var iconImageView: NSImageView!
@IBOutlet weak var itemTitle: NSTextField!

我们按照之前写 SideMenuView试图的方法把 Xib的对象加载进来,具体的方法可以参考上面。

我们设置 View的试图按照宽度和高度自动约束。

self.view.autoresizingMask = [.viewWidthSizable,.viewHeightSizable]

这里说明一点,可选型不是如Objective-C 那样一般用|连接,多个需要放在数组里面。

我们需要的控件已经封装好了,我们现在要做的就是设置 NSTableView的样式为 View Base

B06B6F83-FBBC-4069-802B-AFCF62389B8F

我们删除自动生成的试图,拖拽一个 NSView到 到 Column下面。我们关联 NSTableView的数据源。

4758283F-C1DD-4C44-9C51-FEA669DADDA3

我们在 SideMenuView类里面实现 NSTableView的数据源方法。

BC3FC205-DB67-4781-A977-FFC2DDFF1949

我们通过界面查看器可以看的出来,第一个 Row已经出来了,但是却因为没有设置无法显示。

OSX使用 font-awesome

左侧的图片网站采用 font-awesome框架。 OSX我们使用 FontAwesomeIconFactory框架。

使用 Cocoapods我强烈的建议使用 官方的 App使用

我们设置刚才我们封装的 SideMenuItemViewNSImageView的子类为 NIKFontAwesomeImageView

解决 Cocoapods不能使用 IBDeisgnable

我们在使用 Cocoapods时候不能使用 IBDeisgnable的解决办法。

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['CONFIGURATION_BUILD_DIR'] = '$PODS_CONFIGURATION_BUILD_DIR'
    end
  end
end

很不幸的是在另外的 Xib使用 SideMenuItemView报下面的错误。

E6E2C7AD-960E-4B7E-B418-AB327F3144AC

我们在 Debug IBDeisgnable时候发现抱错下面的代码。

80C7068F-07EB-448D-BBBD-1B42358BEE81

因为我们绑定是对象属于 !类型,但是我们此时还不存在这个变量。故而强行当做存在的使用崩溃了。

到目前为止,我不清楚这个对象没有初始化是为什么导致的。但是只是在 Xib进行初始化 IBDeisgnable抱错,但是可以正常运行的。

但是这样可能不能满足我的要求,我们尽量解决就解决。我们之前的方法里面可以接受一个数组的指针。

我们看看数组里面元素如何。

var views:NSArray = NSArray()
Bundle.main.loadNibNamed("SideMenuItemView", owner: self, topLevelObjects: &views)
96D49D78-164D-4735-80F5-A92558454117

数组里面是有元素的,我们尝试从这里面的元素获取试一下。

func loadXibView() {
    guard let xibView = self.getXibView(nibName: "SideMenuItemView") else {
        return
    }
    xibView.autoresizingMask = [.viewWidthSizable,.viewHeightSizable]
    xibView.frame = self.bounds
    self.addSubview(xibView)
}
    
func getXibView(nibName:String) -> NSView? {
    var views:NSArray = NSArray()
    Bundle.main.loadNibNamed(nibName, owner: self, topLevelObjects: &views)
    var xibView:NSView?
    for any in views {
        guard let view = any as? NSView else {
            continue
        }
        xibView = view
    }
    return xibView
}

我们发现之前报的错误果然消失了。我们可以采用这一种方式来加载试图,我们可以封装一下,方便我们用。

如何在 Swift3获取类名字符串。

NSStringFromClass(type(of:self))
extension NSView {
    func loadXibView() {
        guard let xibView = self.getXibView(nibName: NSStringFromClass(type(of:self))) else {
            return
        }
        xibView.autoresizingMask = [.viewWidthSizable,.viewHeightSizable]
        xibView.frame = self.bounds
        self.addSubview(xibView)
    }
    
    func getXibView(nibName:String) -> NSView? {
        var views:NSArray = NSArray()
        Bundle.main.loadNibNamed(nibName, owner: self, topLevelObjects: &views)
        var xibView:NSView?
        for any in views {
            guard let view = any as? NSView else {
                continue
            }
            xibView = view
        }
        return xibView
    }
}

但是发现竟然加载不出来任何数据,原来我们发现自动生成的类名带有工程前缀。

"Jekyll_Admin_Mac.SideMenuView"

我们可以采用分割字符串使用最后一个。

FE9DB89D-DB70-4F71-B280-8A65921752C2

我们将 SideMenuItemView改成继承与 NIKFontAwesomeImageView

NIKFontAwesomeImageViewIBDeisgnable不能在 Xib预览的。

我们设置 NIKFontAwesomeImageView属性如下。

  • icon Hex : f02d

  • Size : 17

    生成的图片是正方形,并不能和网站的样式可以设置宽度和高度。

  • Color : EBDAC1

我们运行一下发现已经可以正常的运行了。

D18987B2-B0A1-47F5-BBFB-682D44D61367

面向对象设计

我们配置一下 NSTableView的数据源如下:

let menuItemDict = [
    "文章":"F02D",
    "页面":"F15C",
    "数据":"F1C0",
    "文件":"F15B",
    "配置":"F013",
]

我们设置一下 NSTableView数据代理。

public func numberOfRows(in tableView: NSTableView) -> Int {
    return menuItemDict.keys.count
}

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    guard let view = tableView.make(withIdentifier: "SideMenuItemView", owner: self) as? SideMenuItemView else {
        return nil
    }
    view.itemTitle.stringValue = Array(menuItemDict.keys)[row]
    view.iconImageView.iconHex = Array(menuItemDict.values)[row] as NSString
    return view
}

⚠️对于 Swift3里面的 Dictionary的属性 Keys无法作为正常的 Array使用,我们需要用 Array()对其进行初始化。

68A0CE15-89BA-4E79-A705-A431DCDF765C

上图是我们运行起来的效果。但是呢和我们网页的看起来还是有写差别的。

我们在 SideMenuItemView.xib上面的底部添加一条线。布局如下:

54D99DC5-BD43-44EC-8F37-83D156C2C01C

线继承与 BaseView,我们设置颜色为 424242

777EFD44-93A6-4A80-BD5E-92FB76E8A426

虽然线是出来了,但是我们不想让全部出现。

我们在 SideMenuItemView关联刚才的线。

@IBOutlet weak var lineView: BaseView!

我们修改配置如下。

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    guard let view = tableView.make(withIdentifier: "SideMenuItemView", owner: self) as? SideMenuItemView else {
        return nil
    }
    view.itemTitle.stringValue = Array(menuItemDict.keys)[row]
    let values = Array(menuItemDict.values)[row]
    if let hexString = values[0] as? NSString {
        view.iconImageView.iconHex = hexString
    }
    if let hidden = values[1] as? Bool {
        view.lineView.isHidden = hidden
    }
    return view
}

⚠️因为字典的取值是无序的,所以我们这样的写法会导致我们的显示出现问题。

我们修改我们的数据源为一个 Array数组。

let menuItems = [
    ["文章", "F02D", false],
    ["页面", "F15C", true],
    ["数据", "F1C0", false],
    ["文件", "F15B", true],
    ["配置", "F013", false],
]

我们需要修改对应数据赋值。

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    guard let view = tableView.make(withIdentifier: "SideMenuItemView", owner: self) as? SideMenuItemView else {
        return nil
    }
    let values = menuItems[row]
    guard values.count == 3 else {
        return nil
    }
    if let title = values[0] as? String {
        view.itemTitle.stringValue = title
    }
    if let hexIcon = values[1] as? NSString {
        view.iconImageView.iconHex = hexIcon
    }
    if let hidden = values[2] as? Bool {
        view.lineView.isHidden = !hidden
    }
    return view
}

我们运行此时显示如下。

B97289BE-AD47-4616-BAF0-0A62F77DE986

我们给 NSTableView绑定一个方法事件。

@IBAction func didClickRow(_ sender: NSTableView) {
}

我们给 NSTableView新增一个属性是否被选中。然而现在一个问题已经出现,现在这么多的配置需要配置岂不是很麻烦。

这就涉及到面向对象思想,但是我们可以在 Swift中使用 Struct作为我们的配置数据源。

struct SideMenuItemConfiguration {
    let title:String ///< 标题
    let iconHex:String ///< icon 的十六进制字符串
    let hidden:Bool ///< 是否隐藏底部线
    let selected:Bool ///< 是否被选中
}

我们修改我们的数据源:

let menuItems = [
//        ["文章", "F02D", false],
//        ["页面", "F15C", true],
//        ["数据", "F1C0", false],
//        ["文件", "F15B", true],
//        ["配置", "F013", false],
    SideMenuItemConfiguration(title: "文章", iconHex: "F02D", hidden: true, selected: false),
    SideMenuItemConfiguration(title: "页面", iconHex: "F15C", hidden: false, selected: false),
    SideMenuItemConfiguration(title: "数据", iconHex: "F1C0", hidden: true, selected: false),
    SideMenuItemConfiguration(title: "文件", iconHex: "F15B", hidden: false, selected: false),
    SideMenuItemConfiguration(title: "配置", iconHex: "F013", hidden: true, selected: false),
]

再次修改我们的赋值代码。

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    guard let view = tableView.make(withIdentifier: "SideMenuItemView", owner: self) as? SideMenuItemView else {
        return nil
    }
    let configuration = menuItems[row]
    view.itemTitle.stringValue = configuration.title
    view.iconImageView.iconHex = configuration.iconHex as NSString
    view.lineView.isHidden = configuration.hidden
    return view
}

我们的代码比之前要精简一些。

我们在点击 NSTableView点击方法获取选中的 Row,之后让选中数据源状态被选中,其他取消选中。

@IBAction func didClickRow(_ sender: NSTableView) {
    let row = sender.selectedRow
    for (index, configuration) in menuItems.enumerated() {
        configuration.selected = index == row
    }
    sender.reloadData()
}

‼️这段代码会被抱错,因为我们修改了被 let标记的常量,我们修改成 var即可。

而且我们 enumerated()出来的竟然是也是 Let标记的,我们用 var标记。

81D12FF2-A02E-496A-80D9-BC3994745199

我们设置选中的颜色为 ff9900。默认的颜色为 EBDAC1

我们在 SideMenuItemConfiguration新增默认颜色和选中颜色的属性。

let normalColor:NSColor = NSColor(red:1.000, green:0.600, blue:0.000, alpha:1.000) ///< 默认状态颜色
let selectedColor:NSColor = NSColor(red:0.922, green:0.855, blue:0.757, alpha:1.000) ///< 选中的颜色

我们设置默认值这样 之前的代码也可以 正常的编译通过。

我们需要根据选中状态设置图标的颜色还有文字的颜色,这样就要增加一下逻辑。这些都是修改 SideMenuItemView类的内容,为啥不采用赋值,让 SideMenuItemView内部处理呢?

我们说做就做。

var menuItemConfiguration:SideMenuItemConfiguration? {
    didSet {
        guard let configuration = self.menuItemConfiguration else {
            return
        }
        self.itemTitle.stringValue = configuration.title
        self.iconImageView.iconHex = configuration.iconHex as NSString
        self.lineView.isHidden = configuration.hidden
        let color = configuration.selected ? configuration.selectedColor : configuration.normalColor
        self.iconImageView.color = color
        self.itemTitle.textColor = color
    }
}

我们给 SideMenuItemView类新增 menuItemConfiguration属性,当给这个属性设置值的时候我们做出对应处理。

我们现在可以给我们 NSTableView的代码精简如下:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    guard let view = tableView.make(withIdentifier: "SideMenuItemView", owner: self) as? SideMenuItemView else {
        return nil
    }
    let configuration = menuItems[row]
    view.menuItemConfiguration = configuration
    return view
}
F042453B-FB43-481D-8CC0-07A50CD88F2B

但是我们运行起来,却发现全部都是选中的颜色,原来是我们默认颜色和选中颜色配置反了导致,我们修改过来即可。

1F549B40-E8F1-4069-9B3A-7F0ADD6B87C3

此时我们的初始化配置恢复了正常,但是我们点击了没有任何的变化。让我们找一下出现这种现象原因是怎么导致的。

⚠️因为结构体没有被引用,所以便利出来的临时变量属于一个新的地址。我们需要修改临时变量之后替换掉之前数组里面的。

@IBAction func didClickRow(_ sender: NSTableView) {
    let row = sender.selectedRow
    for (index, var configuration) in menuItems.enumerated() {
        configuration.selected = index == row
        menuItems[index] = configuration
    }
    sender.reloadData()
}

‼️此时需要注意的是我们需要修改我们的 menuItemsvar类型。

11

此时我们的效果已经达到了,我们觉得默认启动显示的第一个界面是0元素。

我们绑定界面的元素 NSTableViewSideMenuView

@IBOutlet weak var tableView: NSTableView!

我们把 didClickRow逻辑封装成下面的对象。

func changeTabeleViewState(row:Int, tableView:NSTableView) {
    for (index, var configuration) in menuItems.enumerated() {
        configuration.selected = index == row
        menuItems[index] = configuration
    }
    tableView.reloadData()
}

我们修改 didClickRow的调用。

@IBAction func didClickRow(_ sender: NSTableView) {
    let row = sender.selectedRow
    changeTabeleViewState(row: row, tableView: sender)
}

我们修改 required init?(coder: NSCoder)的代码如下:

required init?(coder: NSCoder) {
    super.init(coder: coder)
    self.loadXibView()
    changeTabeleViewState(row: 0, tableView: self.tableView)
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 本文5500字,大约阅读 15分钟。 6月底会停止在 简书更新,最新的博客地址 君赏博客 关于 NSTableVi...
    君赏阅读 770评论 3 1
  • 简书从6月底停止更新,请前往关注最新的博客地址。 君赏博客 本文5600字大约需要花费15分钟阅读,文章图片过多,...
    君赏阅读 669评论 0 1
  • Swift版本点击这里欢迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh阅读 25,237评论 7 249
  • “宇宙以其不息的欲望将一个歌舞炼为永恒。这欲望有怎样一个人间的姓名,大可忽略不计。” 一年前的今天,是以一种怎样的...
    Alyssa薄禾阅读 368评论 0 2
  • “阿婆,阿婆。柜子上面的小瓶瓶里装了什么?丫头想要。” “装了爱呐,装了阿婆对丫头爱,哪天丫头长大了,嫁人了,阿婆...
    莩树阅读 183评论 0 0