All Projects → Otbivnoe → Framezilla

Otbivnoe / Framezilla

Licence: mit
Elegant library that wraps working with frames with a nice chaining syntax.

Programming Languages

swift
15916 projects

Labels

Projects that are alternatives of or similar to Framezilla

Snapkitextend
SnapKit的扩展,SnapKit类似于Masonry,但是其没有对Arry的设置和对等间距排列的布局等,此扩展是类似Masonry的写法对SnapKit的补充,同时补充九宫格布局方式
Stars: ✭ 110 (-17.91%)
Mutual labels:  layout
Flutter Animations
Flutter animation tutorials, such common animation, flare animation.
Stars: ✭ 119 (-11.19%)
Mutual labels:  layout
Popo
PoPo is the grid layout tool, the best choice for runtime layout.
Stars: ✭ 130 (-2.99%)
Mutual labels:  layout
X6
🚀 JavaScript diagramming library that uses SVG and HTML for rendering.
Stars: ✭ 2,686 (+1904.48%)
Mutual labels:  layout
Stack Up.js
Create fixed width, variable height grid layouts.
Stars: ✭ 117 (-12.69%)
Mutual labels:  layout
The Grid
Grid layout custom element with drag and drop capabilities
Stars: ✭ 122 (-8.96%)
Mutual labels:  layout
Flutter layout grid
A grid-based layout system for Flutter, inspired by CSS Grid Layout
Stars: ✭ 109 (-18.66%)
Mutual labels:  layout
Arclayout
With Arc Layout explore new styles and approaches on material design
Stars: ✭ 1,662 (+1140.3%)
Mutual labels:  layout
React Page Layout
Create layouts for react
Stars: ✭ 117 (-12.69%)
Mutual labels:  layout
Involt
Inject hardware interactions directly into HTML layout.
Stars: ✭ 128 (-4.48%)
Mutual labels:  layout
Draggablemenu
A draggable menu that shows a thumbnail preview of an image grid
Stars: ✭ 117 (-12.69%)
Mutual labels:  layout
Flexlib
FlexLib是一个基于flexbox模型,使用xml文件进行界面布局的框架,融合了web快速布局的能力,让iOS界面开发像写网页一样简单快速
Stars: ✭ 1,569 (+1070.9%)
Mutual labels:  layout
Greedo Layout For Android
Full aspect ratio grid LayoutManager for Android's RecyclerView
Stars: ✭ 1,588 (+1085.07%)
Mutual labels:  layout
Doormat
Let's take a scroll!
Stars: ✭ 111 (-17.16%)
Mutual labels:  layout
Widgetlayout
自定义ViewGroup的集合(有 kotlin 实现分支):提高编写效率和 UI 绘制性能,少嵌套,易用易扩展。
Stars: ✭ 130 (-2.99%)
Mutual labels:  layout
Hierarchy
Layout algorithms for visualizing hierarchical data.
Stars: ✭ 110 (-17.91%)
Mutual labels:  layout
Next Layout
Add persistent and nested layouts to your Next.js projects in a declarative way
Stars: ✭ 120 (-10.45%)
Mutual labels:  layout
Pinlayout
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS/CALayer]
Stars: ✭ 1,870 (+1295.52%)
Mutual labels:  layout
Autoresponsive Vue
Auto responsive grid layout library for Vue.
Stars: ✭ 132 (-1.49%)
Mutual labels:  layout
Xray React
React layout debugger.
Stars: ✭ 128 (-4.48%)
Mutual labels:  layout

Framezilla

Build Status Version Carthage Compatible Platform Swift 4.0 License

Everyone wants to see smooth scrolling, that tableview or collectionview scrolls without any lags and it's right choice. But the constraints do not give it for us. Therefore, we have to choose manual calculation frames, but sometimes, when cell has a complex structure, code has not elegant, beautiful structure.

So, it's library for those, who want to see smooth scrolling with elegant code under the hood!

#Enjoy reading! 🎉

Framezilla is the child of Framer (analog of great layout framework which wraps manually calculation frames with a nice-chaining syntax), but only for Swift.

Installation 🔥

CocoaPods

CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over eighteen thousand libraries and can help you scale your projects elegantly. You can install it with the following command:

$ sudo gem install cocoapods

To integrate Framezilla, simply add the following line to your Podfile:

pod "Framezilla"

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate Framezilla into your Xcode project using Carthage, specify it in your Cartfile:

github "Otbivnoe/Framezilla"

Run carthage update to build the framework and drag the built Framezilla.framework into your Xcode project.

Features 💥

  • [x] Edges with superview
  • [x] Width / Height
  • [x] Top / Left / Bottom / Right
  • [x] CenterX / CenterY / Center (between views)
  • [x] SizeToFit / SizeThatFits / WidthToFit / HeightToFit
  • [x] Container
  • [x] Stack
  • [x] Optional semantic - and
  • [x] Side relations: nui_left, nui_bottom, nui_width, nui_centerX and so on.
  • [x] States
  • [x] Safe area support 😱

Usage 🚀

Size (width, height)

There're a few methods for working with view's size.

You can configure width and height separately:

view.configureFrame { maker in
    maker.width(200).and.height(200)
}

or together with the same result:

view.configureFrame { maker in
    maker.size(width: 200, height: 200)
}

Also in some cases you want to equate the sides of two views with some multiplier.

For example:

view.configureFrame { maker in
    maker.width(to: view1.nui_height, multiplier: 0.5)
    maker.height(to: view1.nui_width) // x1 multiplier - default
}

Edges

Framezilla has two method for comfortable creating edge-relation.

Either you can create edge relation so

view.configureFrame { maker in
    maker.edges(insets: UIEdgeInsetsMake(5, 5, 5, 5)) // UIEdgeInsets.zero - default
}

or

view.configureFrame { maker in
    maker.edges(top: 5, left: 5, bottom: 5, right: 5)
}

the second method has optional parameters, so maker.edges(top: 5, left: 5, bottom: 5) also works correct, but does not create right relation, that in some cases is very useful.

Side relations (Top, left, bottom, right)

You can create edge relation, as shown above, but only use side relations.

view.configureFrame { maker in
    maker.top(inset: 5).and.bottom(inset: 5)
    maker.left(inset: 5).and.right(inset: 5)
}

Also possible to create relations with another view, not a superview:

// Red view
view.configureFrame { maker in
    maker.size(width: 30, height: 30)
    maker.left(to: self.view1.nui_right, inset: 5)
    maker.bottom(to: self.view1.nui_centerY)
}

In iOS 11 Apple has introduced the safe area, similar to topLayoutGuide and bottomLayoutGuide. Framezilla supports this new api as well:

content.configureFrame { maker in
    maker.top(to: nui_safeArea)
    maker.bottom(to: nui_safeArea)
    maker.right(to: nui_safeArea, inset: 10)
    maker.left(to: nui_safeArea, inset: 10)
}

Note: In earlier versions of OS than iOS 11, these methods create a relation to a superview, not the safe area.

Center relations

If you just want to center subview relative superview with constant width and height, this approach specially for you:

view.configureFrame { maker in
    maker.centerY().and.centerX()
    maker.size(width: 100, height: 100)
}

Also possible to set manually centerX and centerY. Just call setCenterX and setCenterY.

What if you want to join the center point of the view with the top right point of another view?

PFF, OKAY.

view.configureFrame { maker in
    maker.centerX(to: self.view1.nui_right, offset: 0)
    maker.centerY(to: self.view1.nui_top) //Zero offset - default
    maker.size(width: 50, height: 50)
}

SizeToFit and SizeThatFits

Very often you should configure labels, so there are some methods for comfortable work with them.

SizeToFit

label.configureFrame { maker in
    maker.sizeToFit() // Configure width and height by text length no limits
    maker.centerX().and.centerY()
}

SizeThatFits

But what if you have to specify edges for label?

label.configureFrame { maker in
    maker.sizeThatFits(size: CGSize(width: 200, height: 100))
    maker.centerX().and.centerY()
}

Container

Use this method when you want to calculate a width and height by wrapping all subviews.

You can also specify a special container relation:

public enum ContainerRelation {
    case width(Number)
    case height(Number)
    case horizontal(left: Number, right: Number)
    case vertical(top: Number, bottom: Number)
}

For instance, if you set a width for a container, only a dynamic height will be calculated.

NOTE:

It atomatically adds all subviews to the container. Don't add subviews manually.

If you don't use a static width for instance, important to understand, that it's not correct to call left and right relations together by subviews, because container sets width relatively width of subviews and here is some ambiguous.

let container = [content1, content2, content3, content4].container(in: view, relation: /* if needed */) {
    content1.configureFrame { maker in
        maker.centerX()
        maker.top()
        maker.size(width: 50, height: 50)
    }

    content2.configureFrame { maker in
        maker.top(to: content1.nui_bottom, inset: 5)
        maker.left()
        maker.size(width: 80, height: 80)
    }

    content3.configureFrame { maker in
        maker.top(to: content1.nui_bottom, inset: 15)
        maker.left(to: content2.nui_right, inset: 5)
        maker.size(width: 80, height: 80)
    }

    content4.configureFrame { maker in
        maker.top(to: content3.nui_bottom, inset: 5)
        maker.right()
        maker.size(width: 20, height: 20)
    }
}

// width and height are already configured
container.configureFrame { maker in
    maker.center()
}

If you have already configured container, then this method will be more convenient for you:

[content1, label1, label2, label3].configure(container: container, relation: .horizontal(left: 20, right: 20)) {
// do configuration
}

Cool things:

Sometimes you want to configure a few views with the same size, for examlple. There is a convinience method:

[view1, view2].configureFrames { maker in
    maker.size(width: 200, height: 100)
}

Stack

Framezilla allows you configure views like stack behaviour. Important to point out correct views order.

[view3, view2, view1].stack(axis: .horizontal, spacing: 3)

States

It's very convenient use many states for animations, because you can just configure all states in one place and when needed change frame for view - just apply needed state! Awesome, is'n it?

demo

override func viewDidLayoutSubviews() {
  
  super.viewDidLayoutSubviews()
  
  // state `DEFAULT_STATE`
  view1.configureFrame { maker in
      maker.centerX().and.centerY()
      maker.width(50).and.height(50)
  }
  
  view1.configureFrame(state: 1) { maker in
      maker.centerX().and.centerY()
      maker.width(100).and.height(100)
  }
}

set new state and animate it:

/* Next time when viewDidLayoutSubviews will be called, `view1` will configure frame for state 1. */
view1.nx_state = 1 // Any hashable value
view.setNeedsLayout()
UIView.animate(withDuration: 1.0) {
    self.view.layoutIfNeeded()
}

Also possible to apply many states in a row:

view1.configureFrame(states: [3, "state"]) { maker in
    maker.size(width: 200, height: 100)
}

Author 💪

Nikita Ermolenko, [email protected]

Thanks 👍

Thanks Artem Novichkov for the name of the library!

Thanks Evgeny Mikhaylov for 'state' feature!

Thanks Anton Kovalev for improving library!

Contribute 🙏

I would love you to contribute to Framezilla, check the CONTRIBUTING file for more info.

License ❗️

Framezilla is available under the MIT license. See the LICENSE file for more info.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].