converting code blocks to use syntax toggle

This commit is contained in:
Luke Parham
2016-04-19 14:50:50 -05:00
parent c78da34a1f
commit 99797fcc30
6 changed files with 196 additions and 17 deletions

View File

@@ -11,7 +11,10 @@ The main difference is that you construct and return the node you'd like managed
Consider the following ASViewController subclass that would like to use a custom table node as its managed node.
```
<div class = "highlight-group">
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
<div class = "code">
<pre lang="objc" class="objcCode">
- (instancetype)initWithModel:(NSArray *)models
{
ASTableNode *tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
@@ -25,7 +28,24 @@ Consider the following ASViewController subclass that would like to use a custom
return self;
}
```
</pre>
<pre lang="swift" class = "swiftCode hidden">
func initWithModel(models: Array<Model>) {
let tableNode = ASTableNode(style:.Plain)
super.initWithNode(tableNode)
self.models = models
self.tableNode = tableNode
self.tableNode.dataSource = self
return self
}
</pre>
</div>
</div>
The most important line is:

View File

@@ -9,24 +9,53 @@ next: cell-node.html
ASDisplayNode is the main view abstraction over UIView and CALayer. It initializes and owns a UIView in the same way UIViews create and own their own backing CALayers.
```
<div class = "highlight-group">
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
<div class = "code">
<pre lang="objc" class="objcCode">
ASDisplayNode *node = [[ASDisplayNode alloc] init];
node.backgroundColor = [UIColor orangeColor];
node.bounds = CGRectMake(0, 0, 100, 100);
NSLog(@"Underlying view: %@", node.view);
```
</pre>
<pre lang="swift" class = "swiftCode hidden">
let node = ASDisplayNode()
node.backgroundColor = UIColor.orangeColor()
node.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
print("Underlying view: \(node.view)")
</pre>
</div>
</div>
A node has all the same properties as a UIView, so using them should feel very familiar to anyone familiar with UIKit.
Properties of both views and layers are forwarded to nodes and can be easily accessed.
```
<div class = "highlight-group">
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
<div class = "code">
<pre lang="objc" class="objcCode">
ASDisplayNode *node = [[ASDisplayNode alloc] init];
node.clipsToBounds = YES; // not .masksToBounds
node.borderColor = [UIColor blueColor]; //layer name when there is no UIView equivalent
NSLog(@"%@", node.layer);
```
NSLog(@"Backing layer: %@", node.layer);
</pre>
<pre lang="swift" class = "swiftCode hidden">
let node = ASDisplayNode()
node.clipsToBounds = true // not .masksToBounds
node.borderColor = UIColor.blueColor() //layer name when there is no UIView equivalent
print("Backing layer: \(node.layer)")
</pre>
</div>
</div>
As you can see, naming defaults to the UIView conventions<a href = "/docs/display-node.html#addendum">***</a> unless there is no UIView equivalent. You also have access to your underlying <code>CALayer</code> just as you would when dealing with a plain <code>UIView</code>.
@@ -36,12 +65,25 @@ When used with one of the <a href = "/docs/getting-started.html#node-containers"
In some cases, it is desirable to initialize a node and provide a view to be used as the backing view. These views are provided via a block that will return a view so that the actual construction of the view can be saved until later. These nodes display step happens synchronously. This is because a node can only be asynchronously displayed when it wraps an _ASDisplayView (the internal view subclass), not when it wraps a plain UIView.
```
<div class = "highlight-group">
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
<div class = "code">
<pre lang="objc" class="objcCode">
ASDisplayNode *node = [ASDisplayNode alloc] initWithViewBlock:^{
SomeView *view = [[SomeView alloc] init];
return view;
}];
```
</pre>
<pre lang="swift" class = "swiftCode hidden">
let node = ASDisplayNode(viewBlock: { () -> UIView! in
let view = SomeView();
return view
})
</pre>
</div>
</div>
Doing this allows you to wrap existing views if that is preferable to converting the UIView subclass to an ASDisplayNode subclass.

View File

@@ -9,17 +9,33 @@ AsyncDisplayKit's layout engine is based on the CSS Box Model. While it is the
The main way you participate in this system is by implementing `-layoutSpecThatFits:` in a node subclass. Here, you declaratively build up layout specs from the inside out, returning the final spec which will contain the rest.
```
<div class = "highlight-group">
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
<div class = "code">
<pre lang="objc" class="objcCode">
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
verticalStack.direction = ASStackLayoutDirectionVertical;
verticalStack.direction = ASStackLayoutDirectionVertical;
verticalStack.spacing = 4.0;
[verticalStack setChildren:_commentNodes];
return verticalStack;
}
```
</pre>
<pre lang="swift" class = "swiftCode hidden">
override func layoutSpecThatFits(constrainedSize: ASSizeRange) {
let verticalStack = ASStackLayoutSpec()
verticalStack.direction = .Vertical
verticalStack.spacing = 4.0
verticalStack.setChildren(_commentNodes)
return verticalStack
}
</pre>
</div>
</div>
Whle this example is extremely simple, it gives you an idea of how to use a layout spec. A stack layout spec, for instance, defines a layout of nodes in which the chlidren will be laid out adjacently, in the direction specified, with the spacing specified. It is very similar to `UIStackView` but with the added benefit of backwards compatibility.
@@ -29,22 +45,41 @@ Layout spec's children can be any object whose class conforms to the `<ASLayouta
Say you wanted to add 8 pts of padding to the stack you've already set up:
<div class = "highlight-group">
<span class="language-toggle"><a data-lang="swift" class="swiftButton">Swift</a><a data-lang="objective-c" class = "active objcButton">Objective-C</a></span>
<div class = "code">
```
<pre lang="objc" class="objcCode">
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
verticalStack.direction = ASStackLayoutDirectionVertical;
verticalStack.direction = ASStackLayoutDirectionVertical;
verticalStack.spacing = 4.0;
[verticalStack setChildren:_commentNodes];
UIEdgeInsets insets = UIEdgeInsetsMake(8, 8, 8, 8);
ASInsetLayoutSpec *insetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets
child:verticalStack];
child:verticalStack];
return insetSpec;
}
```
</pre>
<pre lang="swift" class = "swiftCode hidden">
override func layoutSpecThatFits(constrainedSize: ASSizeRange) {
let verticalStack = ASStackLayoutSpec()
verticalStack.direction = .Vertical
verticalStack.spacing = 4.0
verticalStack.setChildren(_commentNodes)
let insets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
let insetSpec = ASInsetLayoutSpec(insets: insets, child: verticalStack)
return insetSpec
}
</pre>
</div>
</div>
You can easily do that by making that stack the child of an inset layout spec.

View File

@@ -15,6 +15,7 @@
<meta property='og:type' content='website'>
<script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script>
<script type="text/javascript">{'try{Typekit.load();}catch(e){}'}</script>
<script src="/static/toggle.js"></script>
</head>
<body>

View File

@@ -716,3 +716,57 @@ a {
font-size: 36px; } }
.post-title .edit-page-link {
font-size: 18px; }
body {
background-color: #fff;
color: #333;
font-family: "Helvetica Neue",Helvetica,Roboto,Arial,sans-serif;
font-size: 1em;
line-height: 1.5;
}
.language-toggle {
display: block;
box-sizing: border-box;
font-size: 125%
-webkit-font-smoothing: antialiased;
line-height: 1.5;
margin-bottom: 1em;
padding-right: 10px;
}
.language-toggle a.active {
color: #222220 !important;
}
.language-toggle a {
cursor: pointer;
display: block;
float: right;
padding-left: 0.5em;
color: #a3a39e !important;
text-decoration: none;
transition: color 0.1s linear;
}
.language-toggle:after {
content: "";
display: table;
clear: both;
}
.highlight-group {
margin-top: 1em;
font-family: BodyFontFamily,"Georgia Pro",Georgia,Times;
margin: 0;
border-top: 3px #008ED4 solid;
background: #f8f7f5;
border-radius: 4px;
}
.hidden {
display: none;
}
.code {
padding-left: 20px;
padding-bottom: 10px;
}

27
static/toggle.js Normal file
View File

@@ -0,0 +1,27 @@
document.addEventListener("DOMContentLoaded", function() {
var swiftButtons = document.getElementsByClassName("swiftButton");
var objectiveCButons = document.getElementsByClassName("objcButton");
var objcCodes = document.getElementsByClassName("objcCode");
var swiftCodes = document.getElementsByClassName("swiftCode");
var totalCodeSections = swiftButtons.length;
for(var i = 0; i < totalCodeSections; i++) {
swiftButtons[i].onclick = function () {
for (var i = 0; i < totalCodeSections; i++) {
swiftCodes[i].classList.remove("hidden");
objcCodes[i].classList.add("hidden");
objectiveCButons[i].classList.remove("active");
swiftButtons[i].classList.add("active");
};
}
objectiveCButons[i].onclick = function () {
for (var i = 0; i < totalCodeSections; i++) {
swiftCodes[i].classList.add("hidden");
objcCodes[i].classList.remove("hidden");
objectiveCButons[i].classList.add("active");
swiftButtons[i].classList.remove("active");
};
}
}
});