Skip to content

Instantly share code, notes, and snippets.

@lotz84
Last active August 29, 2015 14:07
Show Gist options
  • Save lotz84/cbbbed41ded0ca5d7244 to your computer and use it in GitHub Desktop.
Save lotz84/cbbbed41ded0ca5d7244 to your computer and use it in GitHub Desktop.
Table layout in Swift
import UIKit
infix operator ||| { associativity left precedence 80 }
func ||| (lhs: Layout.Panel, rhs: Layout.Panel) -> Layout.Panel {
return Layout.Panel(forkType: .Horizontal , panel1: lhs, panel2: rhs)
}
infix operator --- { associativity left precedence 80 }
func --- (lhs: Layout.Panel, rhs: Layout.Panel) -> Layout.Panel {
return Layout.Panel(forkType: .Vertical , panel1: lhs, panel2: rhs)
}
class Layout {
struct Margin
{
let top : CGFloat
let right : CGFloat
let bottom : CGFloat
let left : CGFloat
}
enum PanelType
{
case None;
case Fork;
}
enum PanelForkType
{
case Vertical
case Horizontal
}
class Panel
{
let type : PanelType
let forkType : PanelForkType?
var weight : CGFloat
var margin : Margin
let view: UIView?
let panel1 : Panel?
let panel2 : Panel?
var afterLayout: (UIView -> Void)?
convenience init(view : UIView)
{
self.init(view:view, weight:10.0, margin:Margin(top: 0, right: 0, bottom: 0, left: 0))
}
convenience init(view: UIView, weight: CGFloat)
{
self.init(view:view, weight:weight, margin:Margin(top: 0, right: 0, bottom: 0, left: 0))
}
init(view: UIView, weight: CGFloat, margin : Margin)
{
self.type = .None
self.view = view
self.margin = margin
self.weight = weight
}
init(forkType: PanelForkType, panel1 : Panel, panel2: Panel)
{
self.type = .Fork
self.forkType = forkType
self.panel1 = panel1
self.panel2 = panel2
self.margin = Margin(top: 0, right: 0, bottom: 0, left: 0)
self.weight = panel1.weight + panel2.weight
}
func setDefaultWeight()
{
self.weight = 10.0
}
func addTo(view :UIView)
{
let frame = view.frame
self.addTo(view, frame: frame)
}
private func addTo(view: UIView, frame: CGRect)
{
switch(self.type){
case .None:
let x = frame.origin.x + self.margin.left
let y = frame.origin.y + self.margin.top
let width = frame.size.width - self.margin.left - self.margin.right
let height = frame.size.height - self.margin.top - self.margin.bottom
self.view!.frame = CGRect(x:x, y:y, width:width, height:height)
view.addSubview(self.view!)
self.afterLayout?(self.view!)
case .Fork:
var frame1 = CGRectZero
var frame2 = CGRectZero
switch(self.forkType!){
case .Horizontal:
let width = (frame.size.width * self.panel1!.weight) / (self.panel1!.weight + self.panel2!.weight)
frame1 = CGRect(x: frame.origin.x, y: frame.origin.y, width: width, height: frame.size.height)
frame2 = CGRect(x: frame.origin.x+width, y: frame.origin.y, width: frame.size.width - width, height: frame.size.height)
case .Vertical:
let height = (frame.size.height * self.panel1!.weight) / (self.panel1!.weight + self.panel2!.weight)
frame1 = CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.size.width, height: height)
frame2 = CGRect(x: frame.origin.x, y: frame.origin.y+height, width: frame.size.width, height: frame.size.height-height)
}
self.panel1!.addTo(view, frame: frame1)
self.panel2!.addTo(view, frame: frame2)
}
}
}
}
// The MIT License (MIT)
// Copyright © 2014 Hirose Tatsuya
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the “Software”), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
@lotz84
Copy link
Author

lotz84 commented Oct 5, 2014

README
It created by inspired Chris Eidhof - Functional Programming in Swift.
Layout.swift provides easy table layout for display of variety size.
This code is distributed under the terms and conditions of the MIT license.

How to use
Download and import your xcode project.
You can download from here

Altanative
If you want more powerful auto layout library, there is robb/Cartography

Example1

let view0 = UIView()
let view1 = UIView()
let view2 = UIView()
let view3 = UIView()

view0.backgroundColor = UIColor.redColor()
view1.backgroundColor = UIColor.blueColor()
view2.backgroundColor = UIColor.greenColor()
view3.backgroundColor = UIColor.purpleColor()

let p0 = Layout.Panel(view: view0)
let p1 = Layout.Panel(view: view1)
let p2 = Layout.Panel(view: view2)
let p3 = Layout.Panel(view: view3)

let p = p0 ||| p1
        ---
        p2
        ---
        p3

p.addTo(self.view)

Example2

let view0 = UIView()
let view1 = UIView()
let view2 = UIView()
let view3 = UIView()

view0.backgroundColor = UIColor.redColor()
view1.backgroundColor = UIColor.blueColor()
view2.backgroundColor = UIColor.greenColor()
view3.backgroundColor = UIColor.purpleColor()

let p0 = Layout.Panel(view: view0, weight: 20)
let p1 = Layout.Panel(view: view1)
let p2 = Layout.Panel(view: view2)
let p3 = Layout.Panel(view: view3)

let p = p0 ||| p1
        ---
        p2
        ---
        p3

p.addTo(self.view)

Example3

let bg = UIView()
bg.backgroundColor = UIColor.yellowColor()
Layout.Panel(view: bg).addTo(self.view)

let view0 = UIView()
let view1 = UIView()
let view2 = UIView()
let view3 = UIView()

view0.backgroundColor = UIColor.redColor()
view1.backgroundColor = UIColor.blueColor()
view2.backgroundColor = UIColor.greenColor()
view3.backgroundColor = UIColor.purpleColor()

let m = Layout.Margin(top: 10, right: 10, bottom: 10, left:10)

let p0 = Layout.Panel(view: view0, weight: 20, margin: m)
let p1 = Layout.Panel(view: view1)
let p2 = Layout.Panel(view: view2)
let p3 = Layout.Panel(view: view3)

let p = p0 ||| p1
        ---
        p2
        ---
        p3

p.addTo(self.view)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment