xib和storyboard汇总干货(一)

前言

这篇文章是把所有自己开发中使用到的XIB方面的东西做一个汇总,想到啥写啥,个人感觉也差不多能满足开发的基本需求了,如果有什么遗漏,可以留言我再补充;因为是想到啥就去写啥,demo也是临时建的,大部分的东西可能都会以截图进行展示,所以可能比较乱,大家将就看吧...(文章中的所有代码在文章最后面统一给出下载地址,需要的可以下载)

1. Button

btn方面就讲几点:

1.1 如何设置圆角:
圆角
1.2 如何设置边框

边框设置因为涉及到边框的颜色CGColor,所以Key Path中是没办法的,但是可以通过给CALayer添加一个分类设置:

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN

@interface CALayer (XibConfiguration)
@property(nonatomic, assign) UIColor *borderUIColor;
@end

NS_ASSUME_NONNULL_END

#import "CALayer+XibConfiguration.h"
@implementation CALayer (XibConfiguration)

-(void)setBorderUIColor:(UIColor*)color{
    self.borderColor = color.CGColor;
}

-(UIColor*)borderUIColor{
    return [UIColor colorWithCGColor:self.borderColor];
}

@end

然后btn再设置如下:


image.png

最后的效果如图:


image.png
1.3 如何设置指定的角为圆角,如图这样:
image.png

我这里的方法是创建了一个button的子类,然后xib中的button继承这个button类,子类具体如下:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

IB_DESIGNABLE

@interface CYFRoundedButton : UIButton

@property (nonatomic, assign) IBInspectable NSUInteger style;

@property (nonatomic, assign) IBInspectable CGFloat yf_cornerRadius;

@end

NS_ASSUME_NONNULL_END

#import "CYFRoundedButton.h"

@implementation CYFRoundedButton

- (void)makeCorner {
    UIRectCorner corners;
    switch (self.style) {
        case 0:
            corners = UIRectCornerBottomLeft;
            break;
        case 1:
            corners = UIRectCornerTopRight;
            break;
        case 2:
            corners = UIRectCornerTopLeft;
            break;
        case 3:
            corners = UIRectCornerTopRight;
            break;
        case 4:
            corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
            break;
        case 5:
            corners = UIRectCornerTopLeft | UIRectCornerTopRight;
            break;
        case 6:
            corners = UIRectCornerBottomLeft | UIRectCornerTopLeft;
            break;
        case 7:
            corners = UIRectCornerBottomRight | UIRectCornerTopRight;
            break;
        case 8:
            corners = UIRectCornerBottomRight | UIRectCornerTopRight | UIRectCornerTopLeft;
            break;
        case 9:
            corners = UIRectCornerBottomRight | UIRectCornerTopRight | UIRectCornerBottomLeft;
            break;
        default:
            corners = UIRectCornerAllCorners;
            break;
    }
    _yf_cornerRadius = _yf_cornerRadius ? : 10.0f;
    ///< cornerRadii : 每个角椭圆的半径
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(_yf_cornerRadius, _yf_cornerRadius)];
    
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;                                                                                                                                                                                                                                                                                                                                                                                                                       
    self.layer.mask = maskLayer;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self setupUIOnce];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self setupUIOnce];
    }
    return self;
}

- (void)setupUIOnce {
    [self makeCorner];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    [self makeCorner];
}

@end

上面代码这里就解释一点:IB_DESIGNABLE是给xib添加属性的,在@interface前导入,然后 IBInspectable是写在属性前面的,那么类中的属性会出现在xib中,具体如图:


image.png

到这里大家可能就会有很多的想法了,我们居然可以自定义属性,那么是不是可以属性很多xib实现不了的功能呢,这个大家可以去慢慢尝试了,xib是很牛逼的工具.

如果是用纯代码的话设置button的圆角的话, 实际上就是button的layer层的mask属性赋值一个CAShapeLayer, 而这个CAShapeLayer的路径就是我们设置的贝塞尔曲线, 代码如下:

_yf_cornerRadius = _yf_cornerRadius ? : 10.0f;
    ///< cornerRadii : 每个角椭圆的半径
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(_yf_cornerRadius, _yf_cornerRadius)];
    
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;
    self.layer.mask = maskLayer;

1.4 如何给按钮设置图片和文字

效果如图:


这个是左边图片右边文字

操作步骤:
1.选择btn,然后如图:


image.png

2.设置文字和图片的布局方式:


image.png

Force Right-to-Left 是图片在右,文字在左,Force Left-to-Right 是正好相反

  1. 通过下面可以进行微调,到这基本完成:


    image.png
1.5 事件绑定

按住ctrl拖拽到view上这个大家应该都会,就不说了,主要提一点,btn在一个子view上,事件拖到子view上,要注意修改File's Owner为View,不然崩溃:


image.png

button就讲这么多了

20200708:button补充
button设置各种状态时,比如设置过selected时,会发现button的点击效果会有背景色加圆角,这是因为我们的button的style的设置导致的,如果使用system,就是默认使用系统的处理方案,我们只需要选择Custom即可去除这些自带的设置;

2. 给VC和View添加xib文件并绑定
1. 给一个已经创建的VC添加一个xib文件:
image.png

把名称改成我们要添加的VC的名称,系统会自动生成.xib文件,但是还没有绑定
绑定方法就是,按住ctrl 把 File`s owner 拖拽到VIew上,弹出黑框,选择view即可


image.png

绑定后查看如下:


.

如上图说明绑定成功了,到处就完成了;当然如果是创建时勾选xib则不需要自己创建绑定,关键是自己老忘🤣

2. 给View创建xib文件
  1. 同上,添加一个同名的xib
  2. 绑定:我们需要给xib关联上VIew,但是发现 File Owner是不能进行拖线的,因为他们两是同级别的关系,这里我们设置如下:


    image.png

这样就可以了;
给view创建了xib后,设置大小的办法如下:View的Size可以自定义,去掉状态栏

image.png
image.png
3.把用xib搭建的view显示在VC的xib上

只要使用如下代码即可:

#import "TestViewController.h"
#import "SubVIew.h"
@interface TestViewController ()

@property (weak, nonatomic) IBOutlet UIView *coverView;

@end

@implementation TestViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    SubVIew *subV = [[[NSBundle mainBundle] loadNibNamed:@"SubVIew" owner:self options:nil] lastObject];
    
    subV.frame = self.coverView.bounds;
    
    [self.coverView addSubview:subV];
    
    subV.buttonClick = ^{
        NSLog(@"点击");
    };
    
}

@end
3. 将多个view视图合并到一个视图层级
image.png

在布局好了后,如果想把它们作为一个整体,可以如下操作:
按住shift键,选中我们需要设置成一个整体的控件,然后:


image.png

意思就是把这些控件放在一个VIew上显示;
同样,要将其从父类view上移到另一个视图,选择上图中Editor->Unembed 就可以了

4. Lable
4.1 富文本
image.png

如果想实现如上的效果,代码是比较麻烦的,xib可以直接设置


image.png

设置成 attributed属性,然后界面就变成如上了,然后我们从2中选择要变颜色的字体,点击3后会出现颜色选择器


image.png
4.2 文字的自动换行和高度自适应
image.png

文字增加时,label自动增加高度


image.png

实现也很简单:


image.png

设置行数为0,和自动换行,同时约束上,我这边是给了三个,上左右,然后参考label设置了居上label的距离

image.png

然后XIBlable如下:


image.png

当然,你也可以给xiblabel设置上左,然后宽度设置值,高度设置成>=40这样子:


image.png

最后的效果如图:


image.png
4.3 设置宽度的自适应
image.png

上面的label简单的设置添加宽度,高度,左边,上边约束,很简单的常规操作;
然后如下操作: 让其宽度可以自动调整,同时设置自适应的优先级为1000,


image.png

然后我们在设置之前的宽度的优先级,调到小于1000(就是比上面那个小就可以)


image.png

然后我们发现我们的宽度的约束变成了虚线:


image.png

说明设置成功,这里的宽度约束低于自适应的宽度设置;效果:


image.png

但是如果太长,貌似有bug:


image.png

问题还是出在宽度上面,我们改下,如图:


image.png

设置宽度<=300,然后优先级调到最大1000,这样宽度又会变回实线,效果如下:


完美解决

当然这里可以优化下,不设置宽度,设置左右边距,然后左右边距设置优先级,道理是一样的.

Lable的字体加粗和下划线添加没有找到,貌似只能代码处理;

5. textField的XIB界面介绍

1、Text :设置文本框的默认文本。
2、Placeholder : 可以在文本框中显示灰色的字,用于提示用户应该在这个文本框输入什么内容。当这个文本框中输入了数据时,用于提示的灰色的字将会自动消失。
3、Background :
4、Disabled : 若选中此项,用户将不能更改文本框内容。
5、接下来是三个按钮,用来设置对齐方式。
6、Border Style : 选择边界风格。
7、Clear Button : 这是一个下拉菜单,你可以选择清除按钮什么时候出现,所谓清除按钮就是出一个现在文本框右边的小 X ,你可以有以下选择:
7.1 Never appears : 从不出现
7.2 Appears while editing : 编辑时出现
7.3 Appears unless editing :
7.4 Is always visible : 总是可见
8、Clear when editing begins : 若选中此项,则当开始编辑这个文本框时,文本框中之前的内容会被清除掉。比如,你现在这个文本框 A 中输入了 "What" ,之后去编辑文本框 B,若再回来编辑文本框 A ,则其中的"What" 会被立即清除。
9、Text Color : 设置文本框中文本的颜色。
10、Font : 设置文本的字体与字号。
11、Min Font Size : 设置文本框可以显示的最小字体(不过我感觉没什么用)
12、Adjust To Fit : 指定当文本框尺寸减小时,文本框中的文本是否也要缩小。选择它,可以使得全部文本都可见,即使文本很长。但是这个选项要跟 Min Font Size 配合使用,文本再缩小,也不会小于设定的 Min Font Size 。
接下来的部分用于设置键盘如何显示。
13、Captitalization : 设置大写。下拉菜单中有四个选项:
13.1 None : 不设置大写
13.2 Words : 每个单词首字母大写,这里的单词指的是以空格分开的字符串
13.3 Sentances : 每个句子的第一个字母大写,这里的句子是以句号加空格分开的字符串
13.4 All Characters : 所以字母大写
14、Correction : 检查拼写,默认是 YES 。
15、Keyboard : 选择键盘类型,比如全数字、字母和数字等。
16、Appearance:
17、Return Key : 选择返回键,可以选择 Search 、 Return 、 Done 等。
18、Auto-enable Return Key : 如选择此项,则只有至少在文本框输入一个字符后键盘的返回键才有效。
19、Secure : 当你的文本框用作密码输入框时,可以选择这个选项,此时,字符显示为星号。

1.Alignment Horizontal 水平对齐方式
2.Alignment Vertical 垂直对齐方式
3.用于返回一个BOOL值 输入框是否 Selected(选中) Enabled(可用) Highlighted(高亮)

6.UISegmentedControl

Style 属性 :
-- Plain : 分段控件使用最普通的风格;
-- Bordered : 在最普通风格上添加一圈边框;
-- Bar : 分段控件使用工具条风格;

State 属性 :-- Momentary 复选框 : 勾选复选框后, 分段控件不保存控件状态, 如果勾选后, 点击时高亮, 点击后恢复原样;

Tint 属性 : -- 作用 : 设置分段控件被选中的高亮颜色;

Segments 属性 : -- 作用 : 控制分成几段;

Segment 属性 : -- 作用 : 为不同的分段设置对应的 标题, 图片 等内容;

Tittle 属性 : 每个 Segment 都有一个 Tittle 属性, 就是分段按钮每个按钮的标题;
Image 属性: 为不同的 分段 Segment 设置图片;

Behavior 属性 :
-- Enable 复选框 : 用于设置 Segment 是否可用;
-- Selected 复选框 : 用于设置 Segment 是否被选中;

7. UIImageView

设置图片显示的属性 :
-- image (普通) : 访问或设置该控件显示的图片;
-- HighlightedImage (高亮) : 设置图片处于 高亮状态 时显示的图片;

UIImageView 缩放属性 :content Mode
-- Scale To Fill : 不保持 纵横缩放比, 图片完全自适应 UIImageView 控件;
-- Aspect Fit : 保持纵横比缩放, 保证图片长边完全显示出来, 完整显示图片;
-- Aspect Fill : 保持纵横比缩放, 保证图片短边能显示出来, 只在水平或垂直方向某一个方向是完整的, 另一个方向截取;
-- Center : 不缩放图片, 显示图片的中间区域;
-- Top : 不缩放图片, 显示图片的顶部区域;
-- Bottom : 不缩放图片, 显示图片底部区域;
-- Left : 不缩放图片, 显示图片左边区域;
-- Right : 不缩放图片, 显示图片右边区域;
-- Top Left : 不缩放图片, 显示图片左上区域;
-- Top Right : 不缩放图片, 显示图片右上区域;
-- Bottom Left : 不缩放图片, 显示图片左下区域;
-- Bottom Right : 不缩放图片, 显示图片右下区域;

8. UIProgressView 控件属性

Style 属性 :
-- Default : 使用默认风格的进度条;
-- Bar : 工具条风格;
Progress 属性 : 设置已进行的进度的比例值, 取值范围 0.0 ~ 1.0;
Progress Tint 属性 : 已完成的颜色;
Track Tint 属性 : 进度条轨道颜色;

ProgressImage 属性 : 设置进度条完成的图片;-- 注意 : 该属性在 Interface Builder 中没有体现出来;

trackImage 属性 : 设置进度条轨道图片;
-- 注意 : 代码中设置, 界面设计文件中无该属性;

可拉伸图片用法
可拉伸图片作用 : 在上述进度条中, 设置的 progressImage 和 trackImage 必须是可拉伸图片;

(2) 可拉伸图片创建
创建可拉伸图片 : 使用 UIImage 创建 可拉伸图片, 通过 UIEdgeInsets 结构体定义图片拉伸区域;
-- UIEdgeInsets 结构体 : 包括 left, top, right, bottom 四个值;
-- 缩放主体 : 图片缩放只在 UIEdgeInsets 定义的 四个属性值 区域缩放, 图片的中心部分是不进行缩放的;

9. 进度环控件 (UIActivityIndicatorView)

Style 属性 :
-- Large White : 大的 白色 风格;
-- White : 白色风格;
-- Gray : 灰色风格;

(2) Color 属性
Color 属性 :
-- 作用 : 设置进度条的颜色, 设置该属性会覆盖之前选中的风格中的颜色;

(3) Behavior 属性
Behavior 属性 :
-- Animating : 显示出来后立即转动;
-- Hides When Stopped : 停止时自动隐藏;

(4) UIActivityIndicatorView 大小
两种大小 :
-- 标准风格 : 像素值 20 x 20;
-- 大风格 : 像素值 37 x 37;

(5) 控制方法
UIActivityIndicatorView 控制方法 :
-- 开始转动 : startAnimating 方法;
-- 停止转动 : stopAnimating 方法;

10. UISlider

没啥好说的这个...

11.
11. 其他杂

当移动控件等导致警告时,可以:


image.png

一个是更新下约束,一个是去除控件上面的全部约束,就是重新布局了;

【iOS开发】理解IBOutlet、Outlet、referencing outlet、outlet connection

为了能让代码引用nib中的对象,我们在代码中对应的变量前面加上IBOutlet来修饰标记,本身来说它只是个标记,没有什么实际意义,只是用来告诉编译器,这个变量有些特别,是个界面的Outlet(出口),Outlet要和nib文件(也就是storyborad里面的界面)里面的一个对象关联起来(建立了一个connection),一旦建立了连接,我们就说当前这个标记了IBOutlet的变量是nib文件中某对象(object)的referencing outlet(引用出口)

所以说 Outlet是一个变量,是一个带有outlet标记的变量,outlet connection是nib对象创建之后,通过nib里面的定义,在runtime的时候,把它们关联起来的一个机制,这个关联关系建立起来之后,这个outlet就是这个nib对象的referencing outlet

TestView *tView = [[NSBundle mainBundle] loadNibNamed:@"TestView" owner:self options:nil][0];

xib文件是资源文件,放在main bundle中
方法返回的是一个数组而不直接是对象,这是考虑到了Mac开发会有多个对象返回的情况,在iOS开发中就只有一个,固定取[0]就行

以xib的形式保存控件对象的过程其实叫做固化(archive),通过xib文件创建控件的过程叫做解固

一般的UIView对象,代码初始化的时候都会调用initWithFrame:方法,用xib创建的UIView对象是不会调用此方法的
Xib固化相关的初始化函数是:- (instancetype)initWithCoder:(NSCoder *)aDecoder

所以,当以xib创建UIView对象的时候这个函数会调用,之前在initWithFrame:中要做的事情,可以放在initWithCoder:中,或者放在:

- (void)awakeFromNib
{
    [super awakeFromNib];
    //...
}

该函数会在initWithCoder:后调用,两个函数之间的关系有点像VC的loadView和viewDidLoad之间的关系,

由于SB文件与VC一般是一对多的关系,所以我们不仅要知道即将创建的这个VC的实例对象是加载的哪个SB,而且还要知道加载的是该SB中的哪个具体的VC。
storyboard中取VC的方法
SecVC *secVC = [[UIStoryboard storyboardWithName:@"Demo" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"SecVC"];

@"Demo"参数代表SB的文件名字,@"SecVC"代表该VC在SB中的ID,具体使用会在下面的文章中提到。个人建议,该ID最好与类名相同,这样便于将实例化的方法封在基类中

storyboard 中加载VC的基类写法:

#import <UIKit/UIKit.h>

@interface GJBasicController : UIViewController

+ (NSString *)gj_storyboardID;
+ (instancetype)gj_controllerInstanceFromStoryboardWithName:(NSString *)aStoryboardName;

@end
#import "GJBasicController.h"

@implementation GJBasicController

+ (NSString *)gj_storyboardID
{
    return NSStringFromClass([self class]);
}

+ (instancetype)gj_controllerInstanceFromStoryboardWithName:(NSString *)aStoryboardName
{
    return [[UIStoryboard storyboardWithName:aStoryboardName bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:[self storyboardID]];
}

@end

image.png

Class菜单中的Class,一般就是将你的类与xib文件挂钩,我们这里的SecondVC.xib中的View如果要设置成你自定义的View的话就改变这个属性,我们将一个xib与一个UIView子类进行绑定的时候也是改变这个属性的,这是一个很重要的属性

Control + Shift + Command + Enter 打开多个窗口的快捷键,方便拖线

色板:
image.png
文件交互

该标签主要负责xib文件和类的源文件交互用,都是“连线”相关的操作,例如UITableView的delegate与datasoutce,IBAction、IBOutlet等相关,如果我们用了xib的页面产生了莫名其妙的crash那你就要看看是不是自己的“连线”有问题了。

Files Owner

Files Owner指这个xib文件的所属文件是谁,简单的说是xib文件和谁建立起交互,用户通过该xib呈现的页面进行交互的时候谁来处理背后的逻辑。

image.png
Btn事件连线查看
image.png
查看方法与XIB界面控件的对应关系:
image.png
tableView的代理连线:
image.png

用xib建立delegate、datasource和tableView的“连线”,就相当于在Files Owner中写了如下代码:

_testTableView.delegate = self; 
_testTableView.datasource = self;
关于约束的三个按钮:
image.png

第一个约束中,从上到下依次是左对齐、右对齐、上对齐、下对齐、水平对齐、竖直对齐,如下:


image.png

平常都是灰色不能选择的,左右最下面的可以使用,因为这个功能需要选择两个视图,最下面的两个按钮是因为默认了选中当前的视图和它父视图;

image.png

再来个button的约束:

image.png

我让button居中在它的父视图上了(前提是父视图已经在界面上进行了约束,不然报错),具体操作是如下:
1.选择button和它的父视图view
2.如图:


image.png

小技巧:按住command键,把鼠标移到控件上,会有约束的数值显示,如图,很方便调试;
image.png

image.png

还一点要说明的是,button,label,在xib中是可以不给宽高的,系统会默认计算一个合适的宽高显示but的内容

image.png

关于上图的这两个按钮,也是要两个视图,我们可以勾选设置他们的宽高一样;结果如图(btn下面有个VIew的,view是btn的父视图):


image.png

下面的Aspect Ratio 是设置自身的宽高比的

如下图,如果希望button和view是同级的关系,同时他们在同一块区域显示,应该怎么办,直接拖拽会把btn拖到view中,当然,先拖btn在拖view是可以的,但是如果你的view 是已经布局好的呢,怎么办?
其实很简单,只需要在拖动btn时按住command键即可去除包含关系.

image.png
image.png

对应一个控件,其实是可以同时设置它的左右间距的同时设置它的宽度的,虽然左右间距的设置已经可以确定宽度了,只是这样会报错,我们需要设置一个优先级,上面说过了优先级的设置了,结果如图:


image.png
Xib设置了大小后,代码修改的方法:

不使用auto layout时是可以在viewDidLoad:里设置frame的,一旦开启了auto layout,就要注意,通常在viewDidLoad:中设置frame就不再生效,因为iOS5加入的viewWillLayoutSubviews会在viewDidLoad之后调用,而该函数会在执行的时候去加载该文件对应的xib设置的约束,就是说在viewDidLoad:中设置frame的时机太早了,没有生效就又改成了xib中的样子,而且在viewWillLayoutSubviews中修改frame也是不生效的,
方法一:
在viewDidLayoutSubviews中修改frame,这是最简单的方法。

选中xib中的约束(蓝色线段,左边栏Constants里的item)像拖动其他控件一样,将其拖动成为IBOutlet的属性或全局变量

image.png

写成了 属性,就可以在viewDidLoad设置了,也会生效

- (void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];
    [UIView animateWithDuration:1 animations:^{
        self.labelLeftCount.constant = 100;
        [self.view layoutIfNeeded];
    }];
    
    
}
12.storyboard

如下,实现一个vc push到另一个vc,没写一行代码,全是storyboard


image.png

具体步骤如下:
1.拖一个VC进来,加一个btn;
2.给VC添加导航栏,如下操作


image.png

3.然后就是给btn添加事件,拖过去,选择push即可


image.png
跳转传参:

1.绑定VC


image.png

2.设置跳转的segue的标识


image.png

3.传递参数titName方法
#import "ViewController.h"
#import "TestViewController.h"
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.self.view.backgroundColor = [UIColor whiteColor];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"pushTestVC"]) {
        TestViewController *tVC = (TestViewController *)segue.destinationViewController;
        tVC.titName = @"hello world";
    }
}

@end

一个按钮,可能跳转两个或多个VC的处理:

如下图,点击’有选择额跳转,可能进入下面的两个VC中的一个
操作如下


image.png

右键点击VC,出现如图界面,点击Triggered Segues 的+号,拖动到要跳转的VC上,两个要跳转的都如此操作,结果会出现两条线


image.png

设置他们的标识,然后VC代码中:

//点击事件
- (IBAction)choiceJumpBtnClick:(id)sender {
//flag就是一个随便写的判断条件而已
    self.flag = !self.flag;
    
    //跳转方法,通过Identifier而进入到不同的VC中
    if (self.flag) {
        [self performSegueWithIdentifier:@"choiceSec" sender:sender];
    }else{
        [self performSegueWithIdentifier:@"chioceTest" sender:sender];
    }
}

IBAction与IBOutlet

对于一个类来说,方法和属性(在这里属性与字段合在一起表示一个概念)是最重要的两个要素,而IBAction与IBOutlet就是分别标识方法与属性的,它们标识着由它们修饰的方法和属性是来自xib的,我猜它们是给编译器看的。

IBInspectable

前面介绍过了,我们之前讲的东西都是xib是如何影响代码的,而IBInspectable是可以用代码影响xib的

IB_DESIGNABLE

在OC中将IB_DESIGNABLE写在@implementation前
它也是xcode6引入的新功能,它的作用是可以在不运行的情况下把你的代码显示在xib或SB文件中。

两点说明:
1.这是一个针对UI显示的功能,所以只能是在UIView及其子类或者NSView及其子类上生效

2.要想使IBDesignable起作用必须把代码写在drawRect里才能显示,同样的代码,我写在了awakeFromNib里就不会再xib中看出效果,只有写在了drawRect才可以。

IBOutletCollection(ClassName):

将基于IBOutlet创建的对象放在一个NSarray里。

image.png

如图,加入了两个label在labelarr中,当我们选择labelArr,会看到 尝试1,2 都被选中,取得话通过tag值取;

一个单独的xib文件如何添加到VC上并响应事件?

1.关联


image.png

2.VC上创建一个视图用于接收显示accessoryView(可以省略,只是习惯性这样干,好布局)


image.png

3.VC中获取view,显示,同时连线添加响应事件(如果没有关联VC,无法连线)

- (void)viewDidLoad {
    [super viewDidLoad];
   /**
    这里的AccessoryView 只有一个xib文件,没有依托于.h .m
    */
    UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"AccessoryView" owner:self options:nil] firstObject];
    
    view.frame = self.coverVIew.bounds;
    
    [self.coverVIew addSubview:view];
}


- (IBAction)btnClickaction:(id)sender {
    NSLog(@"----点击事件响应了---");
}
Storyboard中的界面跳转的另一种方法:

可以跳转到任意一个界面,方法如下:
假设是在Main.storyboard中,btn跳转到任意一个界面

image.png

这就是一个干干净净的VC,没有进行过连线,在Main.storyboard如果想找到他,则需要设置VC的ID
注意是设置VC 的ID,直接点界面容易勿选成VIew的

image.png

然后就可以进行如下代码操作了

UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    
UIViewController *notsureVC = [mainSB instantiateViewControllerWithIdentifier:@"notsureVC"];

[self presentViewController:notsureVC animated:YES completion:nil];

第二种跳转是一个storyboard的nav跳转到另一个storyboard的nav中

主要是因为@interface UINavigationController : UIViewController 继承关系
实现给一个新的navtonav.storyboard的nav添加id


image.png

然后代码如下:


 UIStoryboard *navSB = [UIStoryboard storyboardWithName:@"navtonav" bundle:[NSBundle mainBundle]];
    
    UINavigationController *navC = [navSB instantiateViewControllerWithIdentifier:@"navNav"];
    
//    [self.navigationController pushViewController:navC animated:YES];
    navC.modalPresentationStyle = 0;
    [self presentViewController:navC animated:YES completion:nil];


设置一个视图是父视图的一半的方法:

如图,我要让imgView是父视图的宽度的一半,然后高度一样,先添加上左下的约束为0,然后设置宽度比例


image.png

比例设置方法是按住ctrl,然后把imgVIew拖线到父视图,会弹出选择框,


image.png

选择Equal Widths,然后


image.png

改成0.5,即为父视图的一半宽度.

高度比例设置是一样的,如果是 要设置对自己的宽高比,如下:

image.png

设置自身的宽高比,这里我设置成了1:1,正方形


image.png
设置一个View上的三个view高度自适应父视图:

我这里以三个子view高度一样为例,效果如图:


image.png

我改变父视图高度,子view也会自动适应
做法如下:

父视图随意给4个约束,关键是子视图,先给第一个view添加三个约束,报错不管它;


image.png

然后第三个view添加三个约束:


image.png

然后是中间的view添加四个约束:


image.png

发现添加完依然报错,因为控制器不知道如何给三个view分配高度,所以按住shift选中三个子view,然后


image.png

设置高度一样,均分,报错消失,完成;

如果高度不是一样,比如高度是1:2:3
image.png

只需要在上面的基础上调整如下的属性更改比例即可


image.png

上面的做法其实很不好,很麻烦,还有更好的办法,这个在下面第二篇中scrollview的横向滑动中我会介绍;
杂七杂八的方法目前就这些,下面是还有tableview和scrollview的,分第二篇写了

参考链接:https://blog.csdn.net/liuchuo/article/details/52560250
https://blog.csdn.net/virgil_li/article/details/51012790
https://www.jianshu.com/p/7d59b9420bba


如果想系统的学习IOS设计模式或者其他IOS技术,底层,逆向,OpenGL等,可以加V:zhuangxiaozhen666,Q3086163058,给你分享资料 密码: 0ivw


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