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. 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 - (instancetype)initWithModel:(NSArray *)models
{ {
ASTableNode *tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain]; ASTableNode *tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
@@ -25,7 +28,24 @@ Consider the following ASViewController subclass that would like to use a custom
return self; 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: 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. 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]; ASDisplayNode *node = [[ASDisplayNode alloc] init];
node.backgroundColor = [UIColor orangeColor]; node.backgroundColor = [UIColor orangeColor];
node.bounds = CGRectMake(0, 0, 100, 100); node.bounds = CGRectMake(0, 0, 100, 100);
NSLog(@"Underlying view: %@", node.view); 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. 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. 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]; ASDisplayNode *node = [[ASDisplayNode alloc] init];
node.clipsToBounds = YES; // not .masksToBounds node.clipsToBounds = YES; // not .masksToBounds
node.borderColor = [UIColor blueColor]; //layer name when there is no UIView equivalent 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>. 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. 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:^{ ASDisplayNode *node = [ASDisplayNode alloc] initWithViewBlock:^{
SomeView *view = [[SomeView alloc] init]; SomeView *view = [[SomeView alloc] init];
return view; 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. 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. 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 - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{ {
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec]; ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
verticalStack.direction = ASStackLayoutDirectionVertical; verticalStack.direction = ASStackLayoutDirectionVertical;
verticalStack.spacing = 4.0; verticalStack.spacing = 4.0;
[verticalStack setChildren:_commentNodes]; [verticalStack setChildren:_commentNodes];
return verticalStack; 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. 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: 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 - (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{ {
ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec]; ASStackLayoutSpec *verticalStack = [ASStackLayoutSpec verticalStackLayoutSpec];
verticalStack.direction = ASStackLayoutDirectionVertical; verticalStack.direction = ASStackLayoutDirectionVertical;
verticalStack.spacing = 4.0; verticalStack.spacing = 4.0;
[verticalStack setChildren:_commentNodes]; [verticalStack setChildren:_commentNodes];
UIEdgeInsets insets = UIEdgeInsetsMake(8, 8, 8, 8); UIEdgeInsets insets = UIEdgeInsetsMake(8, 8, 8, 8);
ASInsetLayoutSpec *insetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets ASInsetLayoutSpec *insetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets
child:verticalStack]; child:verticalStack];
return insetSpec; 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. 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'> <meta property='og:type' content='website'>
<script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script> <script type="text/javascript" src="//use.typekit.net/vqa1hcx.js"></script>
<script type="text/javascript">{'try{Typekit.load();}catch(e){}'}</script> <script type="text/javascript">{'try{Typekit.load();}catch(e){}'}</script>
<script src="/static/toggle.js"></script>
</head> </head>
<body> <body>

View File

@@ -716,3 +716,57 @@ a {
font-size: 36px; } } font-size: 36px; } }
.post-title .edit-page-link { .post-title .edit-page-link {
font-size: 18px; } 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");
};
}
}
});