Skip to content

Introduction and Basic Concepts

Matt Greenfield edited this page Aug 15, 2014 · 7 revisions

MGBoxKit is an iOS toolkit designed to simplify the code required to lay out views and manage user interaction. For layout it provides positioning properties similar to those found in CSS, such as margins, padding, and zIndex. MGBoxKit also functions as a replacement for UITableView and UICollectionView. Interaction events are handled through a lightweight, blocks based API.

CSS-like Layout Features

MGBoxKit provides CSS influenced extensions to the standard UIKit layout engine, such as margins, padding, zIndex, and fixed positioning, as well as some other unique extensions.

For child view layout, MGBoxKit defaults to a layout algorithm similar to CSS's display:block, with each child box positioned below its previous sibling. There is also a grid style layout algorithm, similar to CSS's float:left. And individual child boxes can also optionally exempt themselves from automatic layout, having their position instead defined by their frame origin (thus the same as standard UIView positioning). The child box layout strategy is set by the contentLayoutMode property.

Gesture Handling

box.onTap = ^{
    NSLog(@"you tapped my box!");    
};
box.onSwipe = ^{
    NSLog(@"you swiped, m'lord?");
};
box.onLongPress = ^{
    NSLog(@"you can let go now.");
};

MGBoxKit vs UITableView

MGBoxKit allows rapid building of tables with much simpler code requirements than UITableView. Sections and rows can be added, removed, reordered, and animated with very minimal, easy to read code. No delegates or data sources required.

There is also built in support for lightweight markup (similar to Markdown), allowing you to create bold, italics, underlined, monospaced, and coloured portions of text in table rows with minimal effort. Additionally, table rows can be multiline, automatically adjusting their height to suit the given text.

Table rows accept arbitrary arrays of UIView, NSString, and UIImage objects for their left, middle, and right contents. Font, colour, and line height properties are provided for text styling. Content item spacing, positioning, and alignment can be adjusted with a selection of per row properties.

MGBoxKit vs UICollectionView

Every MGBoxKit box has a child box layout strategy property which can be switched between table and grid. The grid layout strategy is similar to CSS's float:left, but without the float clear hassles.

While UICollectionView provides an advanced, flexible layout engine, capable of a wide and configurable variety of layout strategies, it comes at the price of greater code complexity. An MGBoxKit grid layout can be achieved in one line of code.

Individual boxes in the grid have adjustable margins for each edge, and the container box has adjustable padding. All box adding, removing, and reordering can be animated.

Terminology

Boxes

The MGLayoutBox protocol is the core interface of MGBoxKit, defining the layout and interaction features common to MGBox, MGLine, MGScrollView, and their derivatives. The base class, MGBox, is a thin wrapper around UIView, and can be used in place of UIView in almost any situation.

To distinguish between plain UIView instances and views that implement MGLayoutBox, the latter are referred to as boxes, while all views that are not part of MGBoxKit are referred to as views. When you see the word box, you can think of it as shorthand for "a view that implements the MGLayoutBox protocol", or simply "an MGBoxKit view".

Lines

When discussing table rows in UITableView, the table row class is UITableViewCell, thus rows are referred to as cells. In MGBoxKit, the table row class is MGLine, thus rows are referred to as lines. Although often the term row will be used when talking about tables, and as such should be considered synonymous with line and MGLine.

Containers

When the documentation talks about containers it is referring to a box (thus an MGLayoutBox) that has child boxes. This could mean an MGBox, MGScrollView, or some derivative. This is to distinguish between views that can lay out their children using MGLayoutBox features (margins, padding, zIndex, tables, grids, etc) and views that are not part of MGBoxKit and thus cannot lay out their children using MGLayoutBox features.

Subclassing Tips

While MGLine and MGScrollView rarely need subclassing, it's often useful to subclass MGBox when building things like items in a grid container, or for any generic views that you might want to layout using MGLayoutBox layout rules (eg margins, zIndex, etc).

All MGBox and MGLine instances call setup from initWithFrame: and initWithCoder:, thus making it a good location to apply any custom styling such as margins, padding, text and background colours, fonts, etc. You should probably call [super setup] in here.

Additionally you might want to override the standard layout method, if you want to perform tasks before or after layout. You should almost certainly call [super layout] in your custom layout method.

The Difference Between 'boxes' and 'subviews'

This distinction can present an occasional trap. When layout or layoutWithDuration:completion: are called, the layout engine only applies MGLayoutBox layout rules to boxes in the container's boxes array. All other views in subviews will simply be ignored, with no MGBox style layout rules applied (their zIndex will be treated as 0).

All MGBoxes that are subviews but are not in boxes will be removed during layout. Any MGBoxes in boxes that are not yet subviews will be added as subviews.

So as a general rule of thumb, put MGBoxes into boxes, everything else into subviews, then call one of the layout methods when you're done. As long as you stick to that, you won't get tripped up.

Note that if you are using a boxProvider, the boxes array is ignored and all boxes are expected to come from the container's boxProvider instead. See the Tables and Grids Guide for more details.