Bamboo 1.2.0

Bamboo 1.2.0

张佳伟 维护。



Bamboo 1.2.0

  • 作者:
  • 张佳伟

Bamboo


Carthage Compatible CocoaPods Compatible Swift 4.2 Platform Build Status

一行代码实现自动布局(手动布局在一行中)。

快速查看

view.bb.centerX().below(view2).size(100)

与 iOS 9 API 等价

view.centerXAnchor.constraint(equalTo: view.superview!.centerXAnchor).isActive = true
view.topAnchor.constraint(equalTo: view2.bottomAnchor).isActive = true
view.widthAnchor.constraint(equalToConstant: 100).isActive = true
view.heightAnchor.constraint(equalToConstant: 100).isActive = true

如你所见,Bamboo 消除了大量冗余代码。

  • 使用链式风格,您只需一次性写出视图的名称。
  • 所有方法都分组在 bb 扩展中,因此它们的名称可以简单且简短。
  • 通常隐含了父视图和锚点。
  • 更高级的方法,如 below()size() 使操作更简单。

安装

Carthage

github "wordlessj/Bamboo" ~> 1.0

CocoaPods

pod 'Bamboo', '~> 1.0'

用法

基础知识

UIViewUILayoutGuide 上的所有基本锚点都提供了不带后缀 Anchor 的形式,例如 left 而不是 leftAnchor

// view.left == superview.left
view.bb.left()

// Or use it on UILayoutGuide.
layoutGuide.bb.left()

要指定另一个视图的对应锚点,只需将视图传递给方法。

// view1.left == view2.left
view1.bb.left(view2)

当然,您也可以使用特定的锚点。

// view1.left == view2.right
view1.bb.left(view2.rightAnchor)

使用操作符 +- 添加常量是非常直接的。

// view1.left == view2.right + 10
view1.bb.left(view2.rightAnchor + 10)

// Specific view or anchor can be omitted.
// view.left == superview.left + 10
view.bb.left(10)

对于维度锚点,当只指定了常量时,它将维度设置为常量,而不是匹配到父视图。

// view.width == 10
view.bb.width(10)

width()width(0) 是不同的,前者与父视图匹配,后者设置为 0。

在 iOS 11 中,您可以代替常量使用 SystemSpacing,将乘数传递给初始化器,只支持 + 操作符。

// view1.left == view2.right + 2 * SystemSpacing
view1.bb.left(view2.rightAnchor + SystemSpacing(2))

类似地,使用 >=<= 来指定等式。

// view1.left >= view2.right + 10
view1.bb.left(>=view2.rightAnchor + 10)

要指定优先级,请使用操作符 ~

// view1.left == view2.right + 10 (priority 500)
view1.bb.left(view2.rightAnchor + 10 ~ 500)

对于维度锚点,可以使用 */ 指定乘数。

// view1.width == 2 * view2.width
view1.bb.width(2 * view2)

表达式

表达式传递到基本锚点方法。完全形式

( >= or <= ) item + constant ~ priority

对于维度锚点

( >= or <= ) item * multiplier + constant ~ priority

item 可以是 UIViewUILayoutGuideNSLayoutAnchor。您可以使用 /- 替代 *+。如果未指定等式,则可以在 item 前放置 multiplier 来使其更类似于线性函数。可以创建更复杂的表达式,但为了简单起见,不推荐这样做。

约束

您可以获取用于以后使用的方法生成的单个约束。

let c: NSLayoutConstraint = view.bb.left().constraint

或获取从链中累积的所有约束。

let c: [NSLayoutConstraint] = view.bb.left().top().constraints

激活和禁用

约束可以被启用和禁用,以便更好地控制布局变化。

// Deactivate after creation.
let c: [NSLayoutConstraint] = view.bb.left().top().constraints.deactivate()

// Activate later when appropriate.
c.activate()

高级方法

宽高比

// view.width == 2 * view.height
view.bb.aspectRatio(2)

居中和尺寸

这两种方法与基本锚定方法类似。

  • center(),包括 centerXcenterY
  • size(),包括 widthheight

还有两种设置尺寸的方法。

let cgSize: CGSize
view.bb.size(cgSize)

view.bb.size(width: 10, height: 20)

填充

// Pin all edges.
fill()

// Pin corresponding edge and adjacent edges.
// e.g., fillLeft() pin left, top and bottom.
fill[Left|Right|Top|Bottom|Leading|Trailing]()

// Pin edges on corresponding axis.
// e.g., fillWidth() pin leading and trailing.
fill[Width|Height]()

所有填充方法接受两个可选参数,第一个是填充的视图或 UILayoutGuide,如果为 nil 则为其父视图,第二个是 UIEdgeInsets

// view1 fills view2 with insets.
let insets: UIEdgeInsets
view1.bb.fill(view2, insets: insets)

// If all edge insets are the same, you can pass a single value.
// view1 fills view2 with insets 10.
view1.bb.fill(view2, insets: 10)

周围

  • before()
  • after()
  • above()
  • below()

这些方法和填充方法类似,两个可选参数,除了第二个是间距。

// view1.trailing == view2.leading - 10
view1.bb.before(view2, spacing: 10)

偏移

在iOS 10中,使用 - 运算符在两个轴锚之间创建偏移锚定,然后用 offset() 创建约束。在使用 bb 之前,使用的视图是什么无关紧要。

// view2.left - view1.right == view3.left - view2.right
view1.bb.offset(view2.leftAnchor - view1.rightAnchor, view3.leftAnchor - view2.rightAnchor)

多个项目

你可以同时约束多个项目。有许多基本方法都以此为基础。

// Constrain on each item.
// e.g., Set each item's width to 10.
[view1, view2, view3].bb.each {
    $0.bb.width(10)
}

// Constrain between every two items.
// e.g., view1.left == view2.left, view2.left == view3.left
[view1, view2, view3].bb.between {
    $0.bb.left($1)
}

对单个项目的基本方法在多个项目上也可用。

// Anchor methods take no arguments and align all items' corresponding anchor.
// e.g., Align all views' left.
[view1, view2, view3].bb.left()

// For dimension anchors, you can set values for all items.
// e.g., Set all views' width to 10.
[view1, view2, view3].bb.width(10)

你可以使用固定间距或等间距沿一个轴分配项目。

  • distributeX()
  • distributeY()
  • distributeXEqualSpacing()
  • distributeYEqualSpacing()
// [view1]-10-[view2]-10-[view3]
[view1, view2, view3].bb.distributeX(spacing: 10)

所有distribute方法都包含一个可选的inset参数,你可以指定不添加边距、固定边距或等边距。

// |-[view1]-[view2]-[view3]-|, spacings are all equal.
[view1, view2, view3].bb.distributeXEqualSpacing(inset: .equal)

分组

如果你想要在响应某些事件时激活/禁用一组约束,可以使用group()将约束收集到数组中。

let constraints: [NSLayoutConstraint] = group {
    view1.bb.fill()
    view2.bb.left().top().size(100)
    view3.bb.fillBottom().height(100)
}

手动布局

为什么有自动布局还要手动布局呢?自动布局虽然不错,但有一些性能问题,这时你可能想要切换到手动布局。

手动布局指南

熊猫

熊猫是一个创建视图层次的框架,与Bamboo配合使用,它们可以让在代码中创建视图变得非常简单。

许可证

Bamboo遵从MIT许可证发布。详细信息请参阅LICENSE。