使用xib开发界面
使用xib开发界面
纯代码写界面有时候会降低开发效率,对于一些通用简单的界面,例如程序设置界面,可以使用xib进行开发。
一、关于xib
1. xib和nib
xib文件可以被Xcode编译成nib文件,xib文件本质上是一个xml文件,而nib文件就是编译后的二进制文件,该文件将视图等控件对象封装了起来,而在程序运行起来后,这些对象会被激活。
xib文件本质上是一个xml文件,可以用vim或cat命令查看,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
$ cat ~/Desktop/JLN-1_xib/JLN-1_xib/GrayViewController.xib <!--?xml version= "1.0" encoding= "UTF-8" standalone= "no" ?--> <document type= "com.apple.interfacebuilder3.cocoatouch.xib" version= "3.0" toolsversion= "6254" systemversion= "14b25" targetruntime= "ios.cocoatouch" propertyaccesscontrol= "none" useautolayout= "yes" usetraitcollections= "yes" > <dependencies> <plugin identifier= "com.apple.interfacebuilder.ibcocoatouchplugin" version= "6247" > </plugin identifier= "com.apple.interfacebuilder.ibcocoatouchplugin" version= "6247" ></dependencies> <objects> <placeholder placeholderidentifier= "ibfilesowner" id= "-1" userlabel= "file's owner" customclass= "grayviewcontroller" > <connections> <outlet property= "actionbutton" destination= "edu-ds-gip" id= "qav-o1-ta6" > <outlet property= "titlelabel" destination= "ycj-fh-rdg" id= "xj4-yo-zzp" > <outlet property= "view" destination= "i5m-pr-fkt" id= "sfx-zr-jgt" > </outlet property= "view" destination= "i5m-pr-fkt" id= "sfx-zr-jgt" ></outlet property= "titlelabel" destination= "ycj-fh-rdg" id= "xj4-yo-zzp" ></outlet property= "actionbutton" destination= "edu-ds-gip" id= "qav-o1-ta6" ></connections> <placeholder placeholderidentifier= "ibfirstresponder" id= "-2" customclass= "uiresponder" > <view clearscontextbeforedrawing= "no" contentmode= "scaletofill" id= "i5m-pr-fkt" > <rect key= "frame" x= "0.0" y= "0.0" width= "300" height= "44" > <autoresizingmask key= "autoresizingmask" widthsizable= "yes" heightsizable= "yes" > <subviews> <button opaque= "no" contentmode= "scaletofill" fixedframe= "yes" contenthorizontalalignment= "center" contentverticalalignment= "center" buttontype= "roundedrect" linebreakmode= "middletruncation" translatesautoresizingmaskintoconstraints= "no" id= "edu-ds-gip" > <rect key= "frame" x= "246" y= "7" width= "46" height= "30" > <state key= "normal" title= "button" > <color key= "titleshadowcolor" white= "0.5" alpha= "1" colorspace= "calibratedwhite" > <connections> <action selector= "action:" destination= "-1" eventtype= "touchupinside" id= "svp-jp-gk9" > </action selector= "action:" destination= "-1" eventtype= "touchupinside" id= "svp-jp-gk9" ></connections> <label opaque= "no" userinteractionenabled= "no" contentmode= "left" horizontalhuggingpriority= "251" verticalhuggingpriority= "251" fixedframe= "yes" text= "label" linebreakmode= "tailtruncation" baselineadjustment= "alignbaselines" adjustsfontsizetofit= "no" translatesautoresizingmaskintoconstraints= "no" id= "ycj-fh-rdg" > <rect key= "frame" x= "129" y= "11" width= "42" height= "21" > <fontdescription key= "fontdescription" type= "system" pointsize= "17" > <color key= "textcolor" cocoatouchsystemcolor= "darktextcolor" > <nil key= "highlightedcolor" > </nil key= "highlightedcolor" ></color key= "textcolor" cocoatouchsystemcolor= "darktextcolor" ></fontdescription key= "fontdescription" type= "system" pointsize= "17" ></rect key= "frame" x= "129" y= "11" width= "42" height= "21" ></label opaque= "no" userinteractionenabled= "no" contentmode= "left" horizontalhuggingpriority= "251" verticalhuggingpriority= "251" fixedframe= "yes" text= "label" linebreakmode= "tailtruncation" baselineadjustment= "alignbaselines" adjustsfontsizetofit= "no" translatesautoresizingmaskintoconstraints= "no" id= "ycj-fh-rdg" ></color key= "titleshadowcolor" white= "0.5" alpha= "1" colorspace= "calibratedwhite" ></state key= "normal" title= "button" ></rect key= "frame" x= "246" y= "7" width= "46" height= "30" ></button opaque= "no" contentmode= "scaletofill" fixedframe= "yes" contenthorizontalalignment= "center" contentverticalalignment= "center" buttontype= "roundedrect" linebreakmode= "middletruncation" translatesautoresizingmaskintoconstraints= "no" id= "edu-ds-gip" ></subviews> <color key= "backgroundcolor" white= "1" alpha= "1" colorspace= "custom" customcolorspace= "calibratedwhite" > <nil key= "simulatedstatusbarmetrics" > <nil key= "simulatedtopbarmetrics" > <nil key= "simulatedbottombarmetrics" > <freeformsimulatedsizemetrics key= "simulateddestinationmetrics" > <point key= "canvaslocation" x= "382" y= "285" > </point key= "canvaslocation" x= "382" y= "285" ></freeformsimulatedsizemetrics key= "simulateddestinationmetrics" ></nil key= "simulatedbottombarmetrics" ></nil key= "simulatedtopbarmetrics" ></nil key= "simulatedstatusbarmetrics" ></color key= "backgroundcolor" white= "1" alpha= "1" colorspace= "custom" customcolorspace= "calibratedwhite" ></autoresizingmask key= "autoresizingmask" widthsizable= "yes" heightsizable= "yes" ></rect key= "frame" x= "0.0" y= "0.0" width= "300" height= "44" ></view clearscontextbeforedrawing= "no" contentmode= "scaletofill" id= "i5m-pr-fkt" ></placeholder placeholderidentifier= "ibfirstresponder" id= "-2" customclass= "uiresponder" ></placeholder placeholderidentifier= "ibfilesowner" id= "-1" userlabel= "file's owner" customclass= "grayviewcontroller" ></objects> </document type= "com.apple.interfacebuilder3.cocoatouch.xib" version= "3.0" toolsversion= "6254" systemversion= "14b25" targetruntime= "ios.cocoatouch" propertyaccesscontrol= "none" useautolayout= "yes" usetraitcollections= "yes" > |
nib文件可以在程序的Build目录下找到。
2. xib文件的若干属性
xib文件有以下几个重要的属性:
xib文件名
File’s Owner
xib文件中的视图的Class
xib文件中的视图的Outlet指向
从哪里加载xib,加载xib中的什么视图,都可以根据这几个属性得出。
二、Demo实践
1. 加载xib中File’s Owner为nil的视图
BlueView.xib
MainViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
... @property (strong, nonatomic) UIView *blueView; ... - (void)loadBlueViewFromXIB { // BlueView.xib的File's Owner为nil NSArray *views = [[NSBundle mainBundle] loadNibNamed:@ "BlueView" owner:nil options:nil]; self.blueView = views[0]; // 从xib加载进来的View大小是确定的,但是该视图在父视图中的位置是不确定的 // 此外,视图中的子视图也是原封不动地Load进来的 CGRect rect = _blueView.frame; rect.origin.x += 37.5f; rect.origin.y += 80.0f; _blueView.frame = rect; [self.view addSubview:_blueView]; } |
运行结果:
结论:
File’s Owner为nil的xib文件中的视图属于通用视图,在工程中可以复用
从xib加载进来的View大小是确定的,但是该视图在父视图中的位置是不确定的,因此需要开发者自行指定
视图中的所有子视图会被原封不动地Load进来
2. 加载xib中File’s Owner为self的视图
MainViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
... @property (weak, nonatomic) IBOutlet UIView *greenView; ... - (void)loadGreenViewFromXIB { // GreenView.xib的File's Owner设为self,并建立了一个从该xib的View到self的IBOutlet greenView [[NSBundle mainBundle] loadNibNamed:@ "GreenView" owner:self options:nil]; // 只要self主动调用Load XIB的方法,self持有的IBOutlet指向的视图就会被初始化 // 这里不需要通过views[0]的方式存取视图 CGRect rect = _greenView.frame; rect.origin.x = _blueView.frame.origin.x; rect.origin.y = _blueView.frame.origin.y + 80.0f; _greenView.frame = rect; [self.view addSubview:_greenView]; } |
运行结果:
结论:
File’s Owner不为nil的xib文件中的视图属于专用视图,在工程中不应该被复用
只要self主动调用loadNibNamed:owner:options:方法,self持有的IBOutlet指向的视图就会被初始化
存取xib中的视图不用views[0]的方式,而是通过IBOutlet类型的property进行存取
3. 加载xib中File’s Owner为特定类的视图
RedView.xib
RedViewOwner.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@interface RedViewOwner : NSObject @property (strong, nonatomic) IBOutlet UIView *redView; @end MainViewController.m ... @property (strong, nonatomic) RedViewOwner *redViewOwner; ... - (void)loadRedViewFromXIB { // RedView.xib的File's Owner是RedViewOwner类的实例,并建立了一个从该xib的View到RedViewOwner实例的IBOutlet // 只要通过_redViewOwner主动调用Load XIB的方法,该IBOutlet指向的视图就会被初始化 self.redViewOwner = [RedViewOwner new ]; [[NSBundle mainBundle] loadNibNamed:@ "RedView" owner:_redViewOwner options:nil]; UIView *redView = _redViewOwner.redView; CGRect rect = redView.frame; rect.origin.x = _greenView.frame.origin.x; rect.origin.y = _greenView.frame.origin.y + 80.0f; redView.frame = rect; [self.view addSubview:redView]; } |
运行结果:
结论:
File’s Owner类可以封装视图中的各种逻辑,而不仅仅是提供视图内容
只要通过File’s Owner类主动调用loadNibNamed:owner:options:方法,该IBOutlet指向的视图就会被初始化
4. 加载xib中文件名和视图类名一致的视图(File’s Owner为nil)
YellowView.xib
YellowView.h/m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
@interface YellowView : UIView + (instancetype)viewFromNIB; @property (weak, nonatomic) IBOutlet UILabel *titleLabel; @end @implementation YellowView // Convenience Method + (instancetype)viewFromNIB { // 加载xib中的视图,其中xib文件名和本类类名必须一致 // 这个xib文件的File's Owner必须为空 // 这个xib文件必须只拥有一个视图,并且该视图的class为本类 NSArray *views = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil]; return views[0]; } - (void)awakeFromNib { // 视图内容布局 self.backgroundColor = [UIColor yellowColor]; self.titleLabel.textColor = [UIColor whiteColor]; } @end MainViewController.m ... @property (strong, nonatomic) YellowView *yellowView; ... - (void)loadYellowViewFromXIB { // 说明见YellowView.m的viewFromNIB方法 self.yellowView = [YellowView viewFromNIB]; CGRect rect = _yellowView.frame; UIView *redView = _redViewOwner.redView; rect.origin.x = redView.frame.origin.x; rect.origin.y = redView.frame.origin.y + 80.0f; _yellowView.frame = rect; [self.view addSubview:_yellowView]; } |
运行结果:
结论:
这里的viewFromNib方法只是对loadNibNamed:owner:options:方法的一个简单封装,要求的条件包括: - xib文件名和本类类名必须一致 - 这个xib文件的File’s Owner必须为空 - 这个xib文件必须只拥有一个视图,并且该视图的class为本类
5. 通过UIViewController的initWithNibName:bundle:方法加载xib文件中的视图
BlackView.xib
如果BlackViewController类希望self.view就是xib文件中的View,可以在Connections页中建立view -> File’s Owner的Outlet,如下:
BlackViewController.h/m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@interface BlackViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *titleLabel; // Convenience Method + (instancetype)viewControllerFromNIB; @end @implementation BlackViewController - (void)viewDidLoad { [ super viewDidLoad]; self.view.backgroundColor = [UIColor blackColor]; self.titleLabel.textColor = [UIColor whiteColor]; } + (instancetype)viewControllerFromNIB { return [[BlackViewController alloc] initWithNibName:NSStringFromClass([self class]) bundle:[NSBundle mainBundle]]; } - (void)didReceiveMemoryWarning { [ super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end |
MainViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
... @property (strong, nonatomic) BlackViewController *blackViewController; ... - (void)loadBlackViewFromXIB { self.blackViewController = [[BlackViewController alloc] initWithNibName:@ "BlackViewController" bundle:[NSBundle mainBundle]]; // 或使用Conveniece Method,但要求xib文件名和View Controller类名一致 // self.blackViewController = [BlackViewController viewControllerFromNIB]; UIView *blackView = _blackViewController.view; CGRect rect = blackView.frame; rect.origin.x = _yellowView.frame.origin.x; rect.origin.y = _yellowView.frame.origin.y + 80.0f; blackView.frame = rect; [self.view addSubview:blackView]; } |
运行结果:
结论:
将xib的File’s Owner设成一个UIViewController子类,可以将这个xib文件的视图展示和外部响应事件(例如点击一个按钮触发的点击事件,该视图的手势事件等)全部封装在一个View Controller中,如果把按钮的点击事件封装在一个UIView类中,貌似破坏了MVC模式,因此最好将xib的File’s Owner设成一个UIViewController子类,该类可以通过addChildViewController方法将其添加到现有的View Controller上。如果只是希望加载视图,可以通过viewcontroller.view存取。
如果希望ViewControllerA加载并响应aXIBView中的按钮点击事件,这时必须建立一个aXIBView到ViewControllerA的IBAction,如果ViewControllerA需要拥有多个这样的XIB,那么ViewControllerA会变得非常的庞大,此时可以通过为每一个XIB设置一个ViewController,再让ViewControllerA加载这些Child View Controllers,这样可以将这些事件的响应职责和视图的描绘工作分派给专门的Child View Controller,在减小ViewControllerA体积的同时,也可以提高各个xib的可复用性。
这里的viewControllerFromNIB方法其实就是initWithNibName:bundle:方法的一个简单封装,要求:xib的File’s Owner设为本类。
6. 通过UIViewController+NIB加载xib文件中的View Controller类和其视图
GrayView.xib
UIViewController+NIB.h/m
1
2
3
4
5
6
7
8
9
10
11
12
|
@interface UIViewController (NIB) // 要求xib文件名和View Controller类名一致 + (instancetype)loadFromNib; @end @implementation UIViewController (NIB) + (instancetype)loadFromNib { // [self class]会由调用的类决定 Class controllerClass = [self class]; NSLog(@ "class = %@" , controllerClass); return [[controllerClass alloc] initWithNibName:NSStringFromClass(controllerClass) bundle:[NSBundle mainBundle]]; } @end |
GrayViewController.h/m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
@interface GrayViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *titleLabel; @property (weak, nonatomic) IBOutlet UIButton *actionButton; @end @implementation GrayViewController - (void)viewDidLoad { [ super viewDidLoad]; self.view.backgroundColor = [UIColor grayColor]; self.titleLabel.text = @ "Gray View" ; self.titleLabel.textColor = [UIColor whiteColor]; self.titleLabel.textAlignment = NSTextAlignmentCenter; self.titleLabel.font = [UIFont systemFontOfSize:8.5f]; [self.actionButton setTitle:@ "action" forState:UIControlStateNormal]; [self.actionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; } - (void)didReceiveMemoryWarning { [ super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } // 推荐从XIB文件中加载View Controller的方法,这种方法可以将XIB文件中的视图和其按钮响应事件全部封装在GrayViewController // 如果GrayViewController的按钮响应事件由MainViewController作出响应,那么二者的耦合度就过高 // 建议: // 单纯的通用View展示,使用从xib文件加载视图的方法,File's Owner设为nil // 特定拥有者的View展示,从xib文件加载视图时,File's Owner设为拥有者 // 如果视图中有按钮响应事件,或其它可以和用户交互的事件,建议采用从XIB文件中加载View Controller的方法,这样可以封装UI展示和交互事件 - (IBAction)action:(id)sender { NSLog(@ "action" ); } @end |
MainViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
... @property (strong, nonatomic) GrayViewController *grayViewController; ... - (void)loadGrayViewFromXIB { self.grayViewController = [GrayViewController loadFromNib]; UIView *grayView = _grayViewController.view; UIView *blackView = _blackViewController.view; CGRect rect = grayView.frame; rect.origin.x = blackView.frame.origin.x; rect.origin.y = blackView.frame.origin.y + 80.0f; grayView.frame = rect; [self.view addSubview:grayView]; } |
运行结果:
结论:
这里我专门写了一个UIViewController+NIB的category,只需要调用loadFromNib类方法就可以加载xib中的视图。要求: - xib文件的File’s Owner必须设置为对应的View Controller类。
三、总结
在写界面时同时混用xib和代码可以提高效率,而对xib的使用主要体现在其专用性和通用性上。
对于一些专门的界面,例如App中的设置界面,纯代码写难免会浪费时间,此时可以通过xib文件的拖控件方法来定制。这个xib是专用于某一个界面的,目的是提高效率。
对于一些通用的控件甚至界面,例如一个很漂亮但实现起来非常复杂的按钮,此时可以通过load xib文件中的视图来快速添加。这个xib对于所有视图是共用的,目的是提高可复用性。
对于通用的xib:
如果xib只是单纯的界面展示,那么File’s Owner可以随意。
如果xib中包含了按钮、手势等用户输入事件,那么File’s Owner最好设置为UIViewController类的子类。
四、自问自答
以前使用xib时一直都有点疑问,xib中可以有多个视图控件,但是从xib中load出来的是一个数组,那么怎么确定哪个对象对应的是哪个控件呢?
可以实践一下:
PurpleView.xib
随便在xib文件中加了几个视图。
接下来将其load出来看看:
MainViewController.m
1
2
3
4
5
6
7
8
9
|
- (void)logViewsFromXIB { NSLog(@ "%s begin" , __func__); NSArray *views = [[NSBundle mainBundle] loadNibNamed:@ "PurpleView" owner:nil options:nil]; for (int i = 0; i < views.count; i++) { id obj = views[i]; NSLog(@ "%d : %@" , i, [obj class]); } NSLog(@ "%s end" , __func__); } |
控制台输出如下:
1
2
3
4
5
6
|
2015-01-09 15:03:06.629 JLN-1_xib[3139:121677] -[MainViewController logViewsFromXIB] begin 2015-01-09 15:03:06.635 JLN-1_xib[3139:121677] 0 : UIView 2015-01-09 15:03:06.635 JLN-1_xib[3139:121677] 1 : UIButton 2015-01-09 15:03:06.636 JLN-1_xib[3139:121677] 2 : UITableView 2015-01-09 15:03:06.636 JLN-1_xib[3139:121677] 3 : UILabel 2015-01-09 15:03:06.636 JLN-1_xib[3139:121677] -[MainViewController logViewsFromXIB] end |
结论:
从xib中load出来的views数组中视图对象的排列顺序和xib scene中的对象排列顺序一致(其实就是xml文件中元素的排序而已)。如下:
可以将其打乱并重新运行程序查看结果。
使用xib开发界面的更多相关文章
- Unity iOS混合开发界面切换思路
Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...
- IOS xib生成界面和代码生成界面两种方式混合
应用程序代理类 WKAppDelegate.m // // WKAppDelegate.m // HelloWorld // // Created by easy5 on 13-9-18. // Co ...
- Lakeshore 中文开发界面,示例项目,飞机大战 等 Lakeshore Chinese development interface, sample project, aircraft war, etc
Lakeshore 中文开发界面,示例项目,飞机大战 等 Lakeshore Chinese development interface, sample project, aircraft war, ...
- IOS 使用Interface Builder开发界面入门与技巧
引言: 通过Interface Builder(简称IB)来制作界面一直是iOS开发界饱受争议的方式.主要争议的话题是不太适合团队协作开发,再就是对IB的使用比较生疏,觉得IB只能完成一些很简单的功能 ...
- WinForm开发-界面控件到实体,实体到界面控件自动绑定
在WinForm开发中,我们是不是为绑定界面控件的数据而每个控件每个控件的赋值?在保存修改时是不是也是每个控件每个控件的赋值到实体中?字段一多,那简直就是噩梦.有没有像Web中那样方便的方法直接就自动 ...
- 第二十三篇:在SOUI中使用LUA脚本开发界面
像写网页一样做客户端界面可能是很多客户端开发的理想. 做好一个可以实现和用户交互的动态网页应该包含两个部分:使用html做网页的布局,使用脚本如vbscript,javascript做用户交互的逻辑. ...
- 树莓派入门教程——使用Qt开发界面程序
前言 Qt是一个1991年由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器.Qt是面向对象的框架,使用特 ...
- java springmvc +spring+ mybaits 模块化开发框架 HTML5+css3.0+bootstrap响应式开发界面
需要源码,请加QQ:858-048-581 系统模块 1. 权限管理:点开二级菜单进入三级菜单显示 角色(基础权限)和按钮权限 角色(基础权限): 分角色组和角色,独立分配菜单权限和增 ...
- Swift下使用Xib设计界面
虽然Swift可以纯代码设计界面,不过不利用现有的可视化工具有时候有点效率低.下面是使用xib设计方法,部分代码来自网上. (1)新建View 2.新建View class 3.DemoView.sw ...
随机推荐
- Python 3.x 的一些注意事项
1. reload 被更改 需要 在console执行 from imp import reload 才能调用CT 同时,如果py文件是位于主文件夹深部的位置,可以这么做: import ComicT ...
- bzoj 2597: [Wc2007]剪刀石头布【最小费用最大流】
脑子不太清楚一个zz问题调了好久-- 首先正难则反,因为三元环好像没什么特点,就考虑让非三元环个数最小 考虑非三元环特点,就是环上一定有一个点的入度为2,联系整张图,三元环个数就是每个点C(入度,2) ...
- 洛谷P3306 [SDOI2013]随机数生成器(BSGS)
传送门 感觉我BSGS都白学了……数学渣渣好像没有一道数学题能自己想出来…… 要求$X_{i+1}=aX_i+b\ (mod \ \ p)$ 左右同时加上$\frac{b}{a-1}$,把它变成等比数 ...
- 花花的森林(倍增,LCA
花花的森林,嗯,这是一篇正经的题解. 模拟考的时候没有看出来要怎么求啊,暴力地树形DP.换根.合并.求直径.居然也险险地拿到了80分,不过我们要正经地想正解. 容易想到我们可以让时光倒流,让空间扭转, ...
- route(2018.10.24)
建出最短路图之后\(topsort\)即可. 具体思路: 先用\(dijkstra\)算法在原图中跑出\(1\)号点到\(i\)号节点的最短距离\(dist_1(i)\),将所有边反向后用\(dijk ...
- TYVJ1424占卜DIY
Description lyd学会了使用扑克DIY占卜.方法如下:一副去掉大小王的扑克共52张,打乱后均分为13堆,编号1~13,每堆4张,其中第13堆称作“生命牌”,也就是说你有4条命.这里边,4张 ...
- window git bash客户端vimrc设置tab缩进
从开发机写的代码,弄到windows上的客户端git提交,总是显示格式对不起的问题,问题是再vimrc上tab键的缩进不等于4个空格,然后就需要设置成和linux一样的四格缩进. 安装上git bas ...
- android okhttp和webview session共享
public static OkHttpClient get(Context context){ OkHttpClient.Builder builder = new OkHttpClient.Bui ...
- swift SqliteDB使用
操作步骤: 1,在 Build Phases -> Link Binary With Libraries 中点击加号,添加 libsqlite3.0.tbd 到项目中来 2,创建连接头文件B ...
- 自定义UIButton 实现图片和文字 之间距离和不同样式
喜欢交朋友的加:微信号 dwjluck2013 1.UIButton+ImageTitleSpace.h #import <UIKit/UIKit.h> // 定义一个枚举(包含了四种类型 ...