Skip to content

Instantly share code, notes, and snippets.

@codetalks-new
Last active August 29, 2015 14:24
Show Gist options
  • Select an option

  • Save codetalks-new/b3bedbee22eb34c61f17 to your computer and use it in GitHub Desktop.

Select an option

Save codetalks-new/b3bedbee22eb34c61f17 to your computer and use it in GitHub Desktop.

Revisions

  1. codetalks-new revised this gist Jul 2, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion DrawBinaryTree.swift
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ extension CGRect{

    init(center:CGPoint,width:CGFloat, height:CGFloat){
    origin = CGPoint(x: center.x - width * 0.5, y: center.y - height * 0.5)
    size = CGSize(width: width, height: width)
    size = CGSize(width: width, height: height)
    }

    init(center:CGPoint,size:CGSize){
  2. codetalks-new created this gist Jul 1, 2015.
    151 changes: 151 additions & 0 deletions DrawBinaryTree.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,151 @@
    import UIKit

    class TreeNode{
    let val:Int
    var left:TreeNode?
    var right:TreeNode?
    init(val:Int){
    self.val = val
    }
    }

    struct TreeNodeRect{
    let treeNode:TreeNode
    let rect : CGRect
    init(treeNode:TreeNode,rect:CGRect){
    self.treeNode = treeNode
    self.rect = rect
    }

    var center:CGPoint{
    return rect.center
    }

    }

    extension CGRect{
    init(center:CGPoint,radius:CGFloat){
    origin = CGPoint(x: center.x - radius, y: center.y - radius)
    size = CGSize(width: radius, height: radius)
    }

    init(center:CGPoint,width:CGFloat, height:CGFloat){
    origin = CGPoint(x: center.x - width * 0.5, y: center.y - height * 0.5)
    size = CGSize(width: width, height: width)
    }

    init(center:CGPoint,size:CGSize){
    origin = CGPoint(x: center.x - size.width * 0.5, y: center.y - size.height * 0.5)
    self.size = size
    }

    var center:CGPoint{
    return CGPoint(x: minX + width * 0.5, y: minY + height * 0.5)
    }
    }


    class BinaryTreeView: UIView{
    var binaryTree:TreeNode
    var radius : CGFloat = 30
    var lineSpacing : CGFloat = 60

    var treeNodeRects:[TreeNodeRect] = []

    init(frame:CGRect,binaryTree:TreeNode){
    self.binaryTree = binaryTree
    super.init(frame: frame)
    backgroundColor = UIColor.whiteColor()
    regenerateNodeList()
    }


    override func drawRect(rect: CGRect) {
    let ctx = UIGraphicsGetCurrentContext()


    let lineNodes = treeNodeRects
    let nodeRectByNode = {
    (node:TreeNode) -> TreeNodeRect? in
    for nr in lineNodes{
    if nr.treeNode === node{
    return nr
    }
    }
    return nil
    }

    let drawLineWithPoint = {
    (from:CGPoint,to: CGPoint) -> Void in
    CGContextMoveToPoint(ctx, from.x, from.y)
    CGContextAddLineToPoint(ctx, to.x, to.y)
    }
    for nodeRect in lineNodes{
    let node = nodeRect.treeNode
    if let left = node.left{
    if let leftRect = nodeRectByNode(left){
    drawLineWithPoint(nodeRect.center,leftRect.center)
    }
    }

    if let right = node.right{
    if let rightRect = nodeRectByNode(right){
    drawLineWithPoint(nodeRect.center,rightRect.center)
    }
    }

    }

    CGContextStrokePath(ctx)

    UIColor(white: 0.88, alpha: 1.0)
    for nodeRect in treeNodeRects{
    CGContextFillEllipseInRect(ctx, nodeRect.rect)
    }

    for nodeRect in treeNodeRects{
    drawTextInRect(String(nodeRect.treeNode.val), rect: nodeRect.rect)
    }

    }

    func drawTextInRect(text:String,rect:CGRect){
    let attrs = [NSForegroundColorAttributeName: UIColor.whiteColor(),
    NSFontAttributeName: UIFont.systemFontOfSize(rect.height * 0.5)
    ]
    let attributedText = NSMutableAttributedString(string: text,attributes: attrs)
    let textSize = attributedText.size()
    let textRect = CGRect(center: CGPoint(x: rect.midX, y: rect.midY), size:textSize)

    attributedText.drawInRect(textRect)

    }

    private func regenerateNodeList(){
    treeNodeRects.removeAll()
    arrangeTreeNode(binaryTree, inRect: bounds)
    setNeedsDisplay()
    }

    func arrangeTreeNode(treeNode:TreeNode,inRect rect:CGRect){
    let nodeRect = CGRect(center: CGPoint(x: rect.midX, y: rect.minY + radius), radius: radius)
    treeNodeRects.append(TreeNodeRect(treeNode: treeNode, rect: nodeRect))

    let childRect = rect.rectsByDividing(nodeRect.height + lineSpacing, fromEdge: .MinYEdge).remainder

    let childRects = childRect.rectsByDividing(childRect.width * 0.5, fromEdge: .MinXEdge)
    if let left = treeNode.left{
    arrangeTreeNode(left, inRect: childRects.slice)
    }
    if let right = treeNode.right{
    arrangeTreeNode(right, inRect: childRects.remainder)
    }
    }

    required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
    }
    }

    let binaryTree4 = createBinaryTree4()
    let binaryTreeView = BinaryTreeView(frame: CGRect(x: 0, y: 0, width: 320, height: 480), binaryTree: binaryTree4)