RQVisual 1.0.2

RQVisual 1.0.2

测试已测试
Lang语言 Obj-CObjective C
许可证 MIT
发布上次发布2015年7月

Ryan Quan 维护。



RQVisual 1.0.2

  • Ryan Quan

RQVisual 是一个工具,可以像 Auto Layout 的 Visual Format Language 一样,通过可视化格式在代码中轻松地布局视图。所有视图都使用 Auto Layout 约束进行布局,因此您可以在不编写冗长的 NSLayoutConstraint 语法的情况下获得 Auto Layout 的全部优点。

为什么不直接使用 Auto Layout 的 Visual Format Language 呢?

Auto Layout 的 Visual Format Language 确实可以减少为视图添加多个约束所需的代码行数,但 Visual 的动机是进一步简化这一点。使用 Visual,您可以使用一个方法调用来布局整个视图(当然,这取决于视图的复杂性)。视图之间的隐式填充也被添加,并且可以可选地覆盖或配置到特定的值。这使得可以在不指定视图格式的情况下自动应用视图之间的“标准”间距。

安装

通过 CocoaPods

pod 'RQVisual'

语法文档

有关基本语法文档,请参阅 wiki

示例

以下示例可以采用以下方法之一

+ (UIView *)viewFromVisualFormats:(NSArray *)visualFormats rowSpacingVisualFormat:(NSString *)rowSpacingVisualFormat variableBindings:(NSDictionary *)variableBindings;
+ (void)addSubviewsToView:(UIView *)containerView usingVisualFormats:(NSArray *)visualFormats rowSpacingVisualFormat:(NSString *)rowSpacingVisualFormat variableBindings:(NSDictionary *)variableBindings;

第一种方法将在新的容器视图中返回您的视图,第二种方法将在现有视图中添加您的视图。

还有一个方便的宏,RQVisualDictionaryOfVariableBindings,它将视图名称映射到视图对象本身。这个宏与 NSDictionaryOfVariableBindings 非常相似,但当你传递属性时,它将省略关键名称中的 self. 部分。例如

UIButton *button = ...
self.textView = ...

/**
  Produces @{ @"self.textView": self.textView,
              @"button": button }
*/
NSDictionary *variables1 = NSDictionaryOfVariableBindings(self.textView, button);

/**
  Produces @{ @"textView": self.textView,
              @"button": button }
*/
NSDictionary *variables2 = RQVisualDictionaryOfVariableBindings(self.textView, button);

例1 - 基本布局

假设我想创建一个视图,包含一个固定宽度为 50.0 的 UIImageView 和一个动态宽度的 UILabel。类似这样

|[imageView][       label        ]|

使用 Visual 我们可以这样操作

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"[imageView(50)]-[label]"]
                                       rowSpacingVisualFormat:nil
                                             variableBindings:@{ @"imageView": imageView,
                                                                 @"label":     label }];

这看起来与直接使用 NSLayoutConstraint 的 + constraintsWithVisualFormat:options:metrics:views: 方法非常相似,但是这里已经添加了一些隐式水平和垂直约束

  • imageViewlabel 之间设置了 10.0 的水平填充(默认水平填充)。
  • 两个视图都被约束在创建的视图的上下边缘。
  • 已将imageView限制在创建视图的左边边缘。
  • 已将label限制在创建视图的右边边缘。

如果调整containerView的大小,则label将拉伸宽度,而imageViewlabel都将拉伸高度。

如果我们想固定这些视图的高度,我们只需在视觉格式末尾添加一个特定的高度。

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"[imageView(50)]-[label](60)"]
                                       rowSpacingVisualFormat:nil
                                              variableBindings:@{ @"imageView": imageView,
                                                                  @"label":     label }];

现在,imageViewlabel都将被限制为一个高度为60

需要注意的是,这里的containerView将返回一个不破坏约束的最小可能大小的界面框。对于上述示例,这意味着50 x 60,因为标签具有动态宽度,且允许宽度为0.0

示例 2 - 自定义同一行内视图的间距

可以通过与Auto Layout的视觉格式语言相同的方式应用行中项目之间的间距。

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"|-(30)-[imageView(50)]-(40)-[label](60)"]
                                       rowSpacingVisualFormat:nil
                                             variableBindings:@{ @"imageView": imageView,
                                                                 @"label":     label }];

任何未指定的间距将使用默认值,这些值是在两个项目之间为10(如果您没有设置自己的默认值)并且在与父类视图的对角线上为0

示例 3 - 将同一行内的视图限制为具有相同的宽度

可以指定同一行内的视图应该具有相同的宽度。

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"[imageView(==)]-[label(==)](60)"]
                                       rowSpacingVisualFormat:nil
                                             variableBindings:@{ @"imageView": imageView,
                                                                 @"label":     label }];

在这里,imageViewlabel将具有相同的宽度约束,且两者的高度都为60(高度约束是可有可无的)。

示例 4 - 在一行中居中和固定视图

如果您想居中某些视图或将某些视图固定到某一侧,可以使用`<`指定向左固定,`>`指定向右固定,`<>`用于居中。要生成这样的视图

|[imageView]     [label]     [button]|

我们将这样做

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"[imageView(50)<]-[label(50)<>]-[button(50)>](60)"]
                                       rowSpacingVisualFormat:nil
                                             variableBindings:@{ @"imageView": imageView,
                                                                 @"label":     label,
                                                                 @"button"     button }];

可以一起居中多个视图,例如

|          [imageview][label]           |

只需为两个视图都使用`<>`语法即可

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"[imageView(50)<>]-[label(50)<>](60)"]
                                       rowSpacingVisualFormat:nil
                                             variableBindings:@{ @"imageView": imageView,
                                                                 @"label":     label }];

请注意,对于这些视图固定和居中的示例,您必须在视图中指定宽度约束。这是因为如果视图允许在其宽度上拉伸,则没有固定/居中的意义。

示例 5 - 多行

制作具有多行的视图也很简单。假设我们想要像示例 1 中一样相同的视图,但在其下方我们想要一个UITextView

|[imageView][       label        ]|
|[            textView           ]|

使用视觉格式,将是这样的

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"[imageView(50)]-[label](60)",
                                                                @"[textView]"]
                                       rowSpacingVisualFormat:nil
                                             variableBindings:@{ @"imageView": imageView,
                                                                 @"label":     label,
                                                                 @"textView":  textView }];

在这里,我们已在水平和垂直方向上添加了与示例 1 中相同的隐含约束,但现在还有在textViewimageViewlabel之间的垂直填充。默认垂直填充也是10.0

如果我们想自定义行之间的间距,我们可以这样做

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"r1:[imageView(50)]-[label](60)",
                                                                @"r2:[textView]"]
                                       rowSpacingVisualFormat:@"|-5-[r1]-5-[r2]-15-|"
                                             variableBindings:@{ @"imageView": imageView,
                                                                 @"label":     label,
                                                                 @"textView":  textView }];

在这里,垂直间距将构建如您所预期的那样

  • 第一行(r1)将与其父视图顶部距离为5.0点。
  • 第一行和第二行(r2)将相隔5.0点。
  • 第二行将距离其父视图底部为15.0点。

为了指定行之间的自定义填充,您必须在行中添加标签。通过在视觉格式字符串前加上该行的名称和冒号来实现。名称可以是任何内容,只要它匹配 rowSpacingVisualFormat 中的变量。rowSpacingVisualFormat 字符串的构成方式与 Auto Layout 的视觉格式语言相同,除了使用方括号放置视图,您应使用行标签。

示例 6 - 添加间隔视图

有时,您可能想包含一个类似于视图但用户看不见的间隔视图。为此,您可以使用 _spacer 关键字

UIView *containerView = [RQVisualMaster viewFromVisualFormats:@[@"[imageView(50)]-[_spacer]"]
                                       rowSpacingVisualFormat:nil
                                             variableBindings:@{ @"imageView": imageView }];

这将在 imageView 旁边隐式地为您添加一个不可见的视图。请注意,在这里最好使用 @"[imageView(50)<]"imageView 固定在左侧,或者省略定位语法,只使用 @"[imageView(50)]",因为它们会产生相同的视觉效果。