Last active
August 29, 2015 14:02
-
-
Save hurshagrawal/8bfb5c4a80b17fa1de9d to your computer and use it in GitHub Desktop.
This is a super v0.1 of what I think a new UI API may look like.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Benefits: | |
// - UI is nested, making it easy to tell what contains what UI elements | |
// - All UI is *one file* - no need to hunt down other files/locations (UITableViewCells, for example). | |
// This is a huge boon to productivity. Going back to edit this means I only have to look in one place. | |
// - All event handling info is inline with the UI, making it easy to tell what is interacting how. | |
// (Not very different from current target:action: methods, tbh) | |
// - Styling and layout is separated out, and styling allows for inheritence to keep it DRY | |
// - All UI and styling is declarative (as much as possible), so there's no "order" of doing things, reducing complexity. | |
// Cons: | |
// - Kind of lose out on the type system by using these strings to refer to everything. | |
// There must be some way to make the compiler smarter about this stuff (obviously outside the scope of a library), | |
// or some better solution that still allows you to typecheck everything. | |
let alert = UIView.addView(UIView, name: "alertView", events: nil) { alertView in | |
alertView.addView(UIView, name: "titleBar", events: nil) { titleBar in | |
// Events are inline with view declarations somehow | |
titleBar.addButtonWithName("doneButton", text: "Done", events: [ | |
UIControlEventTouchUpInside: { button in // Not sure if you can add blocks to dictionaries in swift | |
alertView.hidden = true | |
}]) | |
titleBar.addLabelWithName("titleLabel", text: "Welcome") | |
} | |
alertView.addTableViewWithName("tableView", numberOfRows:{ section in section == 0 ? 5 : 2 }) { tableView, indexPath in | |
if indexPath.row == 0 { | |
// The tableView looks for cells named "personCell" that may have already been initialized and can be reused. | |
// If so, reuses them, skips the initialize block, and only runs the configure. | |
// Note: this means we don't need a separate class at all, and avoid having to write + maintain a lot of boilerplate | |
tableView.addCellWithName("personCell", initialize: { | |
return UITableViewCell().addView(UIView, name: "cellView", events: nil) { cellView in | |
cellView.addLabelWithName("nameLabel", text: nil) | |
cellView.addLabelWithName("profileLabel", text: nil) | |
} | |
}, configure: { cell in | |
cell.get("nameLabel").text = self.users[indexPath.row].name | |
cell.get("profileLabel").text = self.users[indexPath.row].profileText | |
} | |
} | |
} | |
} | |
// Styling and UI look and feel code is compartmentalized and allows you to inherit | |
alertView.styleButton("button") { button in | |
button.backgroundColor = UIColor.blackColor | |
button.textColor = UIColor.whiteColor | |
button.layer.cornerRadius = 5.0 | |
} | |
alertView.styleButton("doneButton", inheritsFrom: "button") { button in | |
button.backgroundColor = UIColor.blueColor | |
} | |
// Since we already named all views, getting a dictionary of named subviews is easy | |
alertView.addConstraintsForName("titleBar", visualConstraints: [ | |
"H:|-[titleLabel]-[doneButton]-|" | |
"V:|-[titleLabel]-|", | |
"V:|-[doneButton]-|", | |
], metrics:0 views: alertView.subviewsDictionary()) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment