mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-03-30 16:53:29 +08:00
converting code blocks to use syntax toggle
This commit is contained in:
@@ -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:
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
27
static/toggle.js
Normal 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");
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user