iOS常用第三方庫(kù)之Masonry

一、前言

關(guān)于蘋(píng)果的布局一直是我比較糾結(jié)的問(wèn)題,是寫(xiě)代碼來(lái)控制布局,還是使用storyboard來(lái)控制布局呢?以前我個(gè)人開(kāi)發(fā)的時(shí)候很少使用代碼去寫(xiě)約束,因?yàn)樘闊┝恕K宰罱K選擇的都是AutoLayout進(jìn)行布局,然后拖線設(shè)置約束。不過(guò)好多公司進(jìn)行iOS開(kāi)發(fā)的時(shí)候都會(huì)去動(dòng)態(tài)的修改約束,而且有的會(huì)使用約束去創(chuàng)建一些動(dòng)畫(huà),所以不太去用storyboard進(jìn)行開(kāi)發(fā)(還有就是使用storyboard幾個(gè)人合作的時(shí)候比較麻煩)。反倒更多的是寫(xiě)代碼開(kāi)發(fā)看起來(lái)更加的高效。所以好多開(kāi)發(fā)者都開(kāi)始去使用Masonry。它是一個(gè)封裝的第三方類庫(kù),作用就是來(lái)簡(jiǎn)化開(kāi)發(fā)者寫(xiě)布局約束。

二、“安裝”Masonry

因?yàn)樗且粋€(gè)第三方的類庫(kù),我們可以從這里下載,然后解壓將Masonry那個(gè)文件夾拖入自己的項(xiàng)目文件夾下即可。

三、開(kāi)始使用Masonry

我們?cè)谑褂盟臅r(shí)候,最好在AppDelegate.m的

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

方法中去自定義加載自己的控制器。例如我寫(xiě)的時(shí)候就是這樣:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

self.window.backgroundColor = [UIColor whiteColor];

UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];

self.window.rootViewController = nav;

[self.window makeKeyAndVisible];

return YES;

}

直接加載的我自己寫(xiě)的ViewController。(建議把系統(tǒng)自帶的Main.stoaryboard刪除掉,如果運(yùn)行報(bào)錯(cuò)自己修改,問(wèn)題不大)。

先來(lái)一個(gè)不用Masonry寫(xiě)的最簡(jiǎn)單的布局:(目的是在視圖中添加一個(gè)視圖)

- (void)viewDidLoad {

[super viewDidLoad];

self.title? = @"Basic View";

UIView *view1 = [[UIView alloc] init];

view1.translatesAutoresizingMaskIntoConstraints = NO;

view1.backgroundColor = [UIColor greenColor];

[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(74, 10, 10, 10);

[superview addConstraints:@[

//view1 constraints

[NSLayoutConstraint constraintWithItem:view1

attribute:NSLayoutAttributeTop

relatedBy:NSLayoutRelationEqual

toItem:superview

attribute:NSLayoutAttributeTop

multiplier:1.0

constant:padding.top],

[NSLayoutConstraint constraintWithItem:view1

attribute:NSLayoutAttributeLeft

relatedBy:NSLayoutRelationEqual

toItem:superview

attribute:NSLayoutAttributeLeft

multiplier:1.0

constant:padding.left],

[NSLayoutConstraint constraintWithItem:view1

attribute:NSLayoutAttributeBottom

relatedBy:NSLayoutRelationEqual

toItem:superview

attribute:NSLayoutAttributeBottom

multiplier:1.0

constant:-padding.bottom],

[NSLayoutConstraint constraintWithItem:view1

attribute:NSLayoutAttributeRight

relatedBy:NSLayoutRelationEqual

toItem:superview

attribute:NSLayoutAttributeRight

multiplier:1

constant:-padding.right],

]];

}

運(yùn)行效果如下:

這就是我們用系統(tǒng)的NSLayoutConstraint寫(xiě)的一個(gè)view,然后將這個(gè)view加載到根view中。現(xiàn)在我們用Masonry來(lái)實(shí)現(xiàn)和上邊一樣的效果:

第一步、導(dǎo)入類庫(kù)

#import "Masonry.h"

然后修改代碼如下:

- (void)viewDidLoad {

[super viewDidLoad];

self.title? = @"Basic View";

UIView *superview = self.view;

UIView *view1 = [[UIView alloc] init];

view1.translatesAutoresizingMaskIntoConstraints = NO;

view1.backgroundColor = [UIColor greenColor];

[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(74, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(superview.mas_top).offset(padding.top);

make.left.equalTo(superview.mas_left).offset(padding.left);

make.bottom.equalTo(superview.mas_bottom).offset(-padding.bottom);

make.right.equalTo(superview.mas_right).offset(-padding.right);

}];

}

上面的效果和原來(lái)用NSLayoutConstraint實(shí)現(xiàn)的效果是一樣的,所以就不再貼圖。

我們可以看到,我們使用的一個(gè)mas_makConstrints塊來(lái)進(jìn)行約束設(shè)置。view1指代的就是要添加約束的view(也可以是button,label等等)。然后make的top,left,bottom,right就相當(dāng)于view1的上下左右,然后equalTo()括號(hào)內(nèi)的就是相對(duì)的view,然后offset是偏移量。

還可以更簡(jiǎn)單的實(shí)現(xiàn):

- (void)viewDidLoad {

[super viewDidLoad];

self.title? = @"Basic View";

UIView *superview = self.view;

UIView *view1 = [[UIView alloc] init];

view1.translatesAutoresizingMaskIntoConstraints = NO;

view1.backgroundColor = [UIColor greenColor];

[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(74, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {

make.edges.equalTo(superview).with.insets(padding);

}];

//? ? [view1 mas_makeConstraints:^(MASConstraintMaker *make) {

//? ? ? ? make.top.equalTo(superview.mas_top).offset(padding.top);

//? ? ? ? make.left.equalTo(superview.mas_left).offset(padding.left);

//? ? ? ? make.bottom.equalTo(superview.mas_bottom).offset(-padding.bottom);

//? ? ? ? make.right.equalTo(superview.mas_right).offset(-padding.right);

//? ? }];

}

以上的三種方式都是實(shí)現(xiàn)上邊圖種的效果。

MASViewAttributeNSLayoutAttribute

view.mas_leftNSLayoutAttributeLeft

view.mas_rightNSLayoutAttributeRight

view.mas_topNSLayoutAttributeTop

view.mas_bottomNSLayoutAttributeBottom

view.mas_leadingNSLayoutAttributeLeading

view.mas_trailingNSLayoutAttributeTrailing

view.mas_widthNSLayoutAttributeWidth

view.mas_heightNSLayoutAttributeHeight

view.mas_centerXNSLayoutAttributeCenterX

view.mas_centerYNSLayoutAttributeCenterY

view.mas_baselineNSLayoutAttributeBaseline

以上的屬性對(duì)應(yīng)相應(yīng)的NSLayoutAttribute。

下面就來(lái)看它的使用吧。(先上效果圖,然后再上代碼)

使用一、簡(jiǎn)單的三個(gè)視圖的布局

這個(gè)時(shí)我直接自定義了一個(gè)ZGBasicView視圖,然后添加到了ViewController中。

關(guān)鍵代碼如下:

//

//? ZGBasicView.m

//? MasonryDemo

//

//? Created by zhanggui on 15/10/26.

//? Copyright ? 2015年 zhanggui. All rights reserved.

//

#import "ZGBasicView.h"

#import "View+MASShorthandAdditions.h"

@implementation ZGBasicView

/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

// Drawing code

}

*/

- (id)init {

self = [super init];

if (!self) {

return nil;

}

//? ? ? ? self.translatesAutoresizingMaskIntoConstraints = YES;

//紅色視圖

UIView *redView = [UIView new];

redView.backgroundColor = [UIColor redColor];

redView.layer.borderColor = [UIColor blackColor].CGColor;

redView.layer.borderWidth = 2;

[self addSubview:redView];

//綠色視圖

UIView *greenView = [[UIView alloc] init];

greenView.backgroundColor = [UIColor greenColor];

greenView.layer.borderColor = [UIColor blackColor].CGColor;

greenView.layer.borderWidth = 2;

[self addSubview:greenView];

//藍(lán)色視圖

UIView *blueView = [[UIView alloc] init];

blueView.backgroundColor = [UIColor blueColor];

blueView.layer.borderWidth = 2;

blueView.layer.borderColor = [UIColor blackColor].CGColor;

[self addSubview:blueView];

int padding = 10;

UIView *superview = self;

//with is semantic and option

[redView mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(superview.mas_top).offset(padding); //with with

make.left.equalTo(greenView.mas_right).offset(padding); //without with

make.bottom.equalTo(blueView.mas_top).offset(-padding);

make.right.equalTo(superview.mas_right).offset(-padding);

make.width.equalTo(greenView.mas_width);

make.height.equalTo(@[greenView, blueView]); //can pass array of views

}];

[greenView mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(superview.mas_top).offset(padding);

make.left.equalTo(superview.mas_left).offset(padding);

make.bottom.equalTo(blueView.mas_top).offset(-padding);

make.right.equalTo(redView.mas_left).offset(-padding);

make.width.equalTo(redView.mas_width);

make.height.equalTo(redView.mas_height);

//? ? ? ? ? ? make.height.equalTo(blueView.mas_height);

}];

[blueView mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(greenView.mas_bottom).offset(padding);

make.left.equalTo(superview.mas_left).offset(padding);

make.bottom.equalTo(superview.mas_bottom).offset(-padding);

make.right.equalTo(superview.mas_right).offset(-padding);

make.height.equalTo(greenView.mas_height); //can pass array of attributes

}];

return self;

}

@end

三個(gè)視圖之間的關(guān)系。

場(chǎng)景二、更新視圖

效果圖如下:

實(shí)現(xiàn)代碼如下:(這里也是自定義了一個(gè)View,然后將這個(gè)view加入到了根視圖中)

//

//? UpdateConstraintsView.m

//? MasonryDemo

//

//? Created by zhanggui on 15/10/26.

//? Copyright ? 2015年 zhanggui. All rights reserved.

//

#import "UpdateConstraintsView.h"

#import "Masonry.h"

@interface UpdateConstraintsView ()

@property (nonatomic,strong)UIButton *myButton;

@property (nonatomic,assign)CGSize buttonSize;

@end

@implementation UpdateConstraintsView

- (id)init {

self = [super init];

if (self) {

self.myButton = [UIButton buttonWithType:UIButtonTypeSystem];

[self.myButton setTitle:@"更新約束" forState:UIControlStateNormal];

self.myButton.layer.borderColor = [UIColor blackColor].CGColor;

self.myButton.layer.borderWidth = 2;

[self.myButton addTarget:self action:@selector(changeAction:) forControlEvents:UIControlEventTouchUpInside];

[self addSubview:self.myButton];

self.buttonSize = CGSizeMake(100, 100);

}

return self;

}

/**

Returns whether the receiver depends on the constraint-based layout system.

YES if the view must be in a window using constraint-based layout to function properly, NO otherwise.

*/

+ (BOOL)requiresConstraintBasedLayout {

return YES;

}

/**

Updates constraints for the view.

Custom views that set up constraints themselves should do so by overriding this method. When your custom view notes that a change has been made to the view that invalidates one of its constraints, it should immediately remove that constraint, and then call setNeedsUpdateConstraints to note that constraints need to be updated. Before layout is performed, your implementation of updateConstraints will be invoked, allowing you to verify that all necessary constraints for your content are in place at a time when your custom view’s properties are not changing.

You must not invalidate any constraints as part of your constraint update phase. You also must not invoke a layout or drawing phase as part of constraint updating.

Important:Important

Call [super updateConstraints] as the final step in your implementation.

蘋(píng)果推薦在這個(gè)方法里面添加或者更新約束

*/

- (void)updateConstraints {

[self.myButton mas_updateConstraints:^(MASConstraintMaker *make) {

make.center.equalTo(self);

make.width.equalTo(@(self.buttonSize.width)).priorityLow();? //設(shè)置優(yōu)先級(jí)以及width

make.height.equalTo(@(self.buttonSize.height)).priorityLow();

//設(shè)置myButton的大小小于等于自身view的大小

make.width.lessThanOrEqualTo(self);

make.height.lessThanOrEqualTo(self);

}];

[super updateConstraints];

}

- (void)changeAction:(UIButton *)button {

self.buttonSize = CGSizeMake(self.buttonSize.width*1.2, self.buttonSize.height*1.2);

//告訴約束他們需要更新

[self setNeedsUpdateConstraints];

//update constraints now

[self updateConstraintsIfNeeded];

//設(shè)置更新大小動(dòng)畫(huà)

[UIView animateWithDuration:0.5 animations:^{

/**

Lays out the subviews immediately.

Use this method to force the layout of subviews before drawing. Using the view that receives the message as the root view, this method lays out the view subtree starting at the root.

*/

[self layoutIfNeeded];

}];

}

@end

這里主要使用了mas_updateConstraints:方法

場(chǎng)景三、讓約束復(fù)原

實(shí)現(xiàn)代碼如下:

//

//? ReBackConstraintsView.m

//? MasonryDemo

//可以恢復(fù)原來(lái)的約束

//? Created by zhanggui on 15/10/26.

//? Copyright ? 2015年 zhanggui. All rights reserved.

//

#import "ReBackConstraintsView.h"

#import "Masonry.h"

@interface ReBackConstraintsView ()

@property (nonatomic,strong)UIButton *myButton;

@property (nonatomic,assign)BOOL isAtTop;

@end

@implementation ReBackConstraintsView

- (id)init {

self = [super init];

if (self) {

self.myButton = [UIButton buttonWithType:UIButtonTypeSystem];;

[self.myButton setTitle:@"Move Me!" forState:UIControlStateNormal];

self.myButton.layer.borderColor = UIColor.greenColor.CGColor;

self.myButton.layer.borderWidth = 3;

[self.myButton addTarget:self action:@selector(moveAction:) forControlEvents:UIControlEventTouchUpInside];

[self addSubview:self.myButton];

self.isAtTop = YES;

}

return self;

}

+ (BOOL)requiresConstraintBasedLayout {

return YES;

}

- (void)updateConstraints {

[self.myButton mas_remakeConstraints:^(MASConstraintMaker *make) {

make.width.equalTo(@(100));

make.height.equalTo(@(100));

if (self.isAtTop) {

make.left.equalTo(self.mas_left).offset(10);

make.top.equalTo(self.mas_top).offset(10);

}else {

make.bottom.equalTo(self.mas_bottom).offset(-10);

make.right.equalTo(self.mas_right).offset(-10);

}

}];

[super updateConstraints];

}

- (void)moveAction:(UIButton *)myButton {

self.isAtTop = !self.isAtTop;

//告訴約束他們需要更新

[self setNeedsUpdateConstraints];

//立刻更新視圖約束

[self updateConstraintsIfNeeded];

[UIView animateWithDuration:0.3 animations:^{

[self layoutIfNeeded];

}];

}

/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

// Drawing code

}

*/

@end

這里主要使用了mas_remakeConstraints:方法。

場(chǎng)景四、兩個(gè)視圖的嵌套

實(shí)現(xiàn)代碼:

//

//? NestConstraintsView.m

//? MasonryDemo

//

//? Created by zhanggui on 15/10/26.

//? Copyright ? 2015年 zhanggui. All rights reserved.

//

#import "NestConstraintsView.h"

#import "Masonry.h"

@implementation NestConstraintsView

- (id)init {

self = [super init];

if (self) {

UIView *bigView = [[UIView alloc] init];

bigView.backgroundColor = [UIColor blackColor];

[self addSubview:bigView];

UIView *smallView = [[UIView alloc] init];

smallView.backgroundColor = [UIColor redColor];

[self addSubview:smallView];

[bigView mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(self).offset(20);

make.left.equalTo(self).offset(20);

make.bottom.equalTo(self).offset(-20);

make.right.equalTo(self).offset(-20);

}];

[smallView mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(bigView.mas_top).offset(40);

make.left.equalTo(bigView.mas_left).offset(40);

make.bottom.equalTo(bigView.mas_bottom).offset(-40);

make.right.equalTo(bigView.mas_right).offset(-40);

}];

}

return self;

}

@end

這里和第一個(gè)場(chǎng)景一樣,都是最基本的實(shí)現(xiàn)約束的添加,只不過(guò)相對(duì)參照物不同。

場(chǎng)景五、多個(gè)view一起布局(以組為單位布局)

效果:

實(shí)現(xiàn)代碼:

//

//? GroupButtonView.m

//? MasonryDemo

//

//? Created by zhanggui on 15/10/26.

//? Copyright ? 2015年 zhanggui. All rights reserved.

//

#import "GroupButtonView.h"

#import "Masonry.h"

@implementation GroupButtonView

- (instancetype)init {

self? = [super init];

if (self) {

NSArray *strArr = @[@"10",@"20",@"50",@"100",@"200",@"300"];

NSMutableArray *mutableArr = [[NSMutableArray alloc] initWithCapacity:6];

for (int i=0; i<3; i++) {

UIButton *button = [[UIButton alloc] init];

[button setTitle:strArr[i] forState:UIControlStateNormal];

[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

button.layer.borderColor = [UIColor blackColor].CGColor;

[button addTarget:self action:@selector(show:) forControlEvents:UIControlEventTouchUpInside];

button.layer.borderWidth = 2;

[self addSubview:button];

[mutableArr addObject:button];

}

[mutableArr mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:20 leadSpacing:20 tailSpacing:20];

[mutableArr mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(@120);

make.height.equalTo(@75);

}];

/**

*? -----------------------

*/

NSMutableArray *marr = [NSMutableArray new];

for (int i=3; i<6; i++) {

UIButton *button = [[UIButton alloc] init];

[button setTitle:strArr[i] forState:UIControlStateNormal];

[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

button.layer.borderColor = [UIColor blackColor].CGColor;

[button addTarget:self action:@selector(show:) forControlEvents:UIControlEventTouchUpInside];

button.layer.borderWidth = 2;

[self addSubview:button];

[marr addObject:button];

}

[marr mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedSpacing:20 leadSpacing:20 tailSpacing:20];

[marr mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.equalTo(@200);

make.height.equalTo(@75);

}];

}

return self;

}

- (void)show:(UIButton *)button

{

NSLog(@"%@",button.titleLabel.text);

}

@end

在這里,我們主要就是用到了mas_distributeViewsAlongAxis:...這個(gè)方法,來(lái)萬(wàn)曾一組視圖的布局。

場(chǎng)景六、自己寫(xiě)的一個(gè)簡(jiǎn)單的登錄界面

效果如下:

代碼如下:

//

//? ViewController.m

//? MasonryDemo

//

//? Created by zhanggui on 15/10/8.

//? Copyright ? 2015年 zhanggui. All rights reserved.

//

#import "ViewController.h"

#import "Masonry.h"

#import "ZGBasicView.h"

#import "UpdateConstraintsView.h"

#import "ReBackConstraintsView.h"

#import "NestConstraintsView.h"

#import "GroupButtonView.h"

#import "LoginView.h"

#import "ArrayView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

self.title? = @"登錄";

[self loginView];

//? ? [self addArrayView];

}

- (void)loginView {

LoginView *loginView = [[LoginView alloc] init];

self.view = loginView;

//? ? loginView.frame = self.view.frame;

//? ? [self.view addSubview:loginView];

}

- (void)addArrayView {

ArrayView *arrView = [[ArrayView alloc] init];

self.view = arrView;

}

- (void)groupButtonView {

GroupButtonView *nestView = [[GroupButtonView alloc] init];

nestView.frame = self.view.frame;

//? ? self.view = nestView;

[self.view addSubview:nestView];

}

- (void)nestConstraintsView {

NestConstraintsView *nestView = [[NestConstraintsView alloc] init];

self.view = nestView;

}

- (void)reBackConstraints {

ReBackConstraintsView *rebackView = [[ReBackConstraintsView alloc] init];

self.view = rebackView;

}

- (void)updateConstraintsView {

UpdateConstraintsView *updateView = [[UpdateConstraintsView alloc] init];

self.view = updateView;

}

- (void)simpleView {

ZGBasicView *basicView = [[ZGBasicView alloc] init];

//? ? [self.view addSubview:basicView];

self.view = basicView;

}

- (void)firstSimpleView {

UIView *superview = self.view;

UIView *view1 = [[UIView alloc] init];

view1.translatesAutoresizingMaskIntoConstraints = NO;

view1.backgroundColor = [UIColor greenColor];

[superview addSubview:view1];

UIEdgeInsets padding = UIEdgeInsetsMake(74, 10, 10, 10);

[view1 mas_makeConstraints:^(MASConstraintMaker *make) {

make.edges.equalTo(superview).with.insets(padding);

}];

//? ? [view1 mas_makeConstraints:^(MASConstraintMaker *make) {

//? ? ? ? make.top.equalTo(superview.mas_top).offset(padding.top);

//? ? ? ? make.left.equalTo(superview.mas_left).offset(padding.left);

//? ? ? ? make.bottom.equalTo(superview.mas_bottom).offset(-padding.bottom);

//? ? ? ? make.right.equalTo(superview.mas_right).offset(-padding.right);

//? ? }];

}

@end

大家可以簡(jiǎn)單的看一下,寫(xiě)的比較簡(jiǎn)單,應(yīng)該很容易理解的。(橫屏的距離上邊的高度沒(méi)有處理太好,將就著看吧)

簡(jiǎn)單就介紹這么多了。

附:

1、源碼下載地址:http://pan.baidu.com/s/1o6083G2

2、Masonry Git地址:https://github.com/SnapKit/Masonry

最后編輯于
?著作權(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閱讀 228,363評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,305評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,962評(píng)論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,727評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,193評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,411評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,777評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,978評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,216評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,642評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,878評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,657評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,960評(píng)論 2 373

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

  • 一、先做一個(gè)比較 使用系統(tǒng)自帶的方法 使用 masonry 實(shí)現(xiàn)同樣效果,代碼進(jìn)行比較: 第一種方法: 第二種方法...
    magic_pill閱讀 1,696評(píng)論 1 4
  • (一)Masonry介紹 Masonry是一個(gè)輕量級(jí)的布局框架 擁有自己的描述語(yǔ)法 采用更優(yōu)雅的鏈?zhǔn)秸Z(yǔ)法封裝自動(dòng)布...
    木易林1閱讀 2,364評(píng)論 0 3
  • Masonry是一個(gè)輕量級(jí)的布局框架,擁有自己的描述語(yǔ)法,采用更優(yōu)雅的鏈?zhǔn)秸Z(yǔ)法封裝自動(dòng)布局,簡(jiǎn)潔明了并具有高可讀性...
    3dcc6cf93bb5閱讀 1,782評(píng)論 0 1
  • iOS_autoLayout_Masonry 概述 Masonry是一個(gè)輕量級(jí)的布局框架與更好的包裝AutoLay...
    指尖的跳動(dòng)閱讀 1,178評(píng)論 1 4
  • 這僅僅是個(gè)一虛構(gòu)故事! 紅狐領(lǐng)著三個(gè)孩子向這座城市唯一的動(dòng)物生態(tài)園區(qū)走去。這大過(guò)年的,園區(qū)還是那樣擁擠,排著長(zhǎng)長(zhǎng)的...
    廣羽三妞閱讀 261評(píng)論 1 1