mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
[Build] Move aside ASLayoutSpecPlayground-Swift for now, as it is causing an Xcode 8.0-specific build failure.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
//: [Photo With Outset Icon Overlay](PhotoWithOutsetIconOverlay)
|
||||
|
||||
import AsyncDisplayKit
|
||||
|
||||
extension HorizontalStackWithSpacer {
|
||||
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
usernameNode.style.flexShrink = 1.0
|
||||
postLocationNode.style.flexShrink = 1.0
|
||||
|
||||
let verticalStackSpec = ASStackLayoutSpec.vertical()
|
||||
verticalStackSpec.style.flexShrink = 1.0
|
||||
|
||||
// if fetching post location data from server, check if it is available yet
|
||||
if postLocationNode.attributedText != nil {
|
||||
verticalStackSpec.children = [usernameNode, postLocationNode]
|
||||
} else {
|
||||
verticalStackSpec.children = [usernameNode]
|
||||
}
|
||||
|
||||
let spacerSpec = ASLayoutSpec()
|
||||
spacerSpec.style.flexGrow = 1.0
|
||||
spacerSpec.style.flexShrink = 1.0
|
||||
|
||||
// horizontal stack
|
||||
let horizontalStack = ASStackLayoutSpec.horizontal()
|
||||
horizontalStack.alignItems = .center // center items vertically in horiz stack
|
||||
horizontalStack.justifyContent = .start // justify content to left
|
||||
horizontalStack.style.flexShrink = 1.0
|
||||
horizontalStack.style.flexGrow = 1.0
|
||||
horizontalStack.children = [verticalStackSpec, spacerSpec, postTimeNode]
|
||||
|
||||
// inset horizontal stack
|
||||
let insets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
|
||||
let headerInsetSpec = ASInsetLayoutSpec(insets: insets, child: horizontalStack)
|
||||
headerInsetSpec.style.flexShrink = 1.0
|
||||
headerInsetSpec.style.flexGrow = 1.0
|
||||
|
||||
return headerInsetSpec
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HorizontalStackWithSpacer().show()
|
||||
|
||||
//: [Index](Index)
|
||||
@@ -0,0 +1,24 @@
|
||||
/*:
|
||||
## ⚠️ You must start by building the Sample framework ⚠️
|
||||
Once that succeeds, you should not have to build until you update AsyncDisplayKit!
|
||||
What you see here isn't comprehensive, but you should be able to tweak the variables to familiarize yourself with the layout APIs.
|
||||
- - -
|
||||
|
||||
## Table of Contents
|
||||
* [Stack Layout](StackLayout)
|
||||
* [Photo With Inset Text Overlay](PhotoWithInsetTextOverlay)
|
||||
* [Photo With Outset Icon Overlay](PhotoWithOutsetIconOverlay)
|
||||
* [Horizontal Stack With Spacer](HorizontalStackWithSpacer)
|
||||
|
||||
- - -
|
||||
Tips:
|
||||
1. Make sure to show the Assistant Editor in order to preview your code changes. You can do this with either of the following:
|
||||
- (cmd + opt/alt + ⮐)
|
||||
- View → Assistant Editor → Show Assistant Editor, to see the preview
|
||||
1. Make sure that **Timeline** as the element selected in the Assistant Editor
|
||||
1. You might have to click on stop/start (the one at the bottom of the screen, under the editor) a few times in case the timeline isn't updating.
|
||||
- - -
|
||||
Solutions to Common Issues:
|
||||
1. If you're getting errors regarding **import Sample_Sources**, simply restart Xcode and try again.
|
||||
1. If you're getting issues with threading, restart the test until it works.
|
||||
*/
|
||||
@@ -0,0 +1,26 @@
|
||||
//: [Stack Layout](StackLayout)
|
||||
|
||||
import AsyncDisplayKit
|
||||
|
||||
let userImageHeight = 60
|
||||
|
||||
extension PhotoWithInsetTextOverlay {
|
||||
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
photoNode.style.preferredSize = CGSize(width: userImageHeight * 2, height: userImageHeight * 2)
|
||||
let backgroundImageAbsoluteSpec = ASAbsoluteLayoutSpec(children: [photoNode])
|
||||
|
||||
let insets = UIEdgeInsets(top: CGFloat.infinity, left: 12, bottom: 12, right: 12)
|
||||
let textInsetSpec = ASInsetLayoutSpec(insets: insets,
|
||||
child: titleNode)
|
||||
|
||||
let textOverlaySpec = ASOverlayLayoutSpec(child: backgroundImageAbsoluteSpec, overlay: textInsetSpec)
|
||||
|
||||
return textOverlaySpec
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PhotoWithInsetTextOverlay().show()
|
||||
|
||||
//: [Photo With Outset Icon Overlay](PhotoWithOutsetIconOverlay)
|
||||
@@ -0,0 +1,28 @@
|
||||
//: [Photo With Inset Text Overlay](PhotoWithInsetTextOverlay)
|
||||
|
||||
import AsyncDisplayKit
|
||||
|
||||
extension PhotoWithOutsetIconOverlay {
|
||||
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
let iconWidth: CGFloat = 40
|
||||
let iconHeight: CGFloat = 40
|
||||
|
||||
iconNode.style.preferredSize = CGSize(width: iconWidth, height: iconWidth)
|
||||
photoNode.style.preferredSize = CGSize(width: 150, height: 150)
|
||||
|
||||
let x: CGFloat = 150
|
||||
let y: CGFloat = 0
|
||||
|
||||
iconNode.style.layoutPosition = CGPoint(x: x, y: y)
|
||||
photoNode.style.layoutPosition = CGPoint(x: iconWidth * 0.5, y: iconHeight * 0.5);
|
||||
|
||||
let absoluteLayoutSpec = ASAbsoluteLayoutSpec(children: [photoNode, iconNode])
|
||||
return absoluteLayoutSpec;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PhotoWithOutsetIconOverlay().show()
|
||||
|
||||
//: [Horizontal Stack With Spacer](HorizontalStackWithSpacer)
|
||||
@@ -0,0 +1,31 @@
|
||||
//: [Index](Index)
|
||||
/*:
|
||||
In this example, you can experiment with stack layouts.
|
||||
*/
|
||||
import AsyncDisplayKit
|
||||
|
||||
extension StackLayout {
|
||||
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
// Try commenting out the flexShrink to see its consequences.
|
||||
subtitleNode.style.flexShrink = 1.0
|
||||
|
||||
let stackSpec = ASStackLayoutSpec(direction: .horizontal,
|
||||
spacing: 5,
|
||||
justifyContent: .start,
|
||||
alignItems: .start,
|
||||
children: [titleNode, subtitleNode])
|
||||
|
||||
let insetSpec = ASInsetLayoutSpec(insets: UIEdgeInsets(top: 5,
|
||||
left: 5,
|
||||
bottom: 5,
|
||||
right: 5),
|
||||
child: stackSpec)
|
||||
return insetSpec
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
StackLayout().show()
|
||||
|
||||
//: [Photo With Inset Text Overlay](PhotoWithInsetTextOverlay)
|
||||
@@ -0,0 +1,26 @@
|
||||
import PlaygroundSupport
|
||||
import AsyncDisplayKit
|
||||
|
||||
public protocol ASPlayground: class {
|
||||
func display(inRect: CGRect)
|
||||
}
|
||||
|
||||
extension ASPlayground {
|
||||
public func display(inRect rect: CGRect) {
|
||||
var rect = rect
|
||||
if rect.size == .zero {
|
||||
rect.size = CGSize(width: 400, height: 400)
|
||||
}
|
||||
|
||||
guard let nodeSelf = self as? ASDisplayNode else {
|
||||
assertionFailure("Class inheriting ASPlayground must be an ASDisplayNode")
|
||||
return
|
||||
}
|
||||
|
||||
let constrainedSize = ASSizeRange(min: rect.size, max: rect.size)
|
||||
_ = ASCalculateRootLayout(nodeSelf, constrainedSize)
|
||||
nodeSelf.frame = rect
|
||||
PlaygroundPage.current.needsIndefiniteExecution = true
|
||||
PlaygroundPage.current.liveView = nodeSelf.view
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import AsyncDisplayKit
|
||||
|
||||
fileprivate let fontSize: CGFloat = 20
|
||||
|
||||
public class HorizontalStackWithSpacer: ASDisplayNode, ASPlayground {
|
||||
public let usernameNode = ASTextNode()
|
||||
public let postLocationNode = ASTextNode()
|
||||
public let postTimeNode = ASTextNode()
|
||||
|
||||
override public init() {
|
||||
super.init()
|
||||
backgroundColor = .white
|
||||
|
||||
automaticallyManagesSubnodes = true
|
||||
setupNodes()
|
||||
}
|
||||
|
||||
private func setupNodes() {
|
||||
usernameNode.backgroundColor = .yellow
|
||||
usernameNode.attributedText = NSAttributedString.attributedString(string: "hannahmbanana", fontSize: fontSize, color: .darkBlueColor(), firstWordColor: nil)
|
||||
|
||||
postLocationNode.backgroundColor = .lightGray
|
||||
postLocationNode.maximumNumberOfLines = 1;
|
||||
postLocationNode.attributedText = NSAttributedString.attributedString(string: "San Fransisco, CA", fontSize: fontSize, color: .lightBlueColor(), firstWordColor: nil)
|
||||
|
||||
postTimeNode.backgroundColor = .brown
|
||||
postTimeNode.attributedText = NSAttributedString.attributedString(string: "30m", fontSize: fontSize, color: .lightGray, firstWordColor: nil)
|
||||
}
|
||||
|
||||
// This is used to expose this function for overriding in extensions
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
return ASLayoutSpec()
|
||||
}
|
||||
|
||||
public func show() {
|
||||
display(inRect: CGRect(x: 0, y: 0, width: 450, height: 100))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import AsyncDisplayKit
|
||||
|
||||
public class PhotoWithInsetTextOverlay: ASDisplayNode, ASPlayground {
|
||||
public let photoNode = ASNetworkImageNode()
|
||||
public let titleNode = ASTextNode()
|
||||
|
||||
override public init() {
|
||||
super.init()
|
||||
backgroundColor = .white
|
||||
|
||||
automaticallyManagesSubnodes = true
|
||||
setupNodes()
|
||||
}
|
||||
|
||||
private func setupNodes() {
|
||||
photoNode.url = URL(string: "http://asyncdisplaykit.org/static/images/layout-examples-photo-with-inset-text-overlay-photo.png")
|
||||
photoNode.backgroundColor = .black
|
||||
|
||||
titleNode.backgroundColor = .blue
|
||||
titleNode.maximumNumberOfLines = 2
|
||||
titleNode.truncationAttributedText = NSAttributedString.attributedString(string: "...", fontSize: 16, color: .white, firstWordColor: nil)
|
||||
titleNode.attributedText = NSAttributedString.attributedString(string: "family fall hikes", fontSize: 16, color: .white, firstWordColor: nil)
|
||||
}
|
||||
|
||||
// This is used to expose this function for overriding in extensions
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
return ASLayoutSpec()
|
||||
}
|
||||
|
||||
public func show() {
|
||||
display(inRect: CGRect(x: 0, y: 0, width: 120, height: 120))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import AsyncDisplayKit
|
||||
|
||||
fileprivate let userImageHeight = 60
|
||||
|
||||
public class PhotoWithOutsetIconOverlay: ASDisplayNode, ASPlayground {
|
||||
public let photoNode = ASNetworkImageNode()
|
||||
public let iconNode = ASNetworkImageNode()
|
||||
|
||||
override public init() {
|
||||
super.init()
|
||||
backgroundColor = .white
|
||||
|
||||
automaticallyManagesSubnodes = true
|
||||
setupNodes()
|
||||
}
|
||||
|
||||
private func setupNodes() {
|
||||
photoNode.url = URL(string: "http://asyncdisplaykit.org/static/images/layout-examples-photo-with-outset-icon-overlay-photo.png")
|
||||
photoNode.backgroundColor = .black
|
||||
|
||||
iconNode.url = URL(string: "http://asyncdisplaykit.org/static/images/layout-examples-photo-with-outset-icon-overlay-icon.png")
|
||||
iconNode.imageModificationBlock = ASImageNodeRoundBorderModificationBlock(10, .white)
|
||||
}
|
||||
|
||||
// This is used to expose this function for overriding in extensions
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
return ASLayoutSpec()
|
||||
}
|
||||
|
||||
public func show() {
|
||||
display(inRect: CGRect(x: 0, y: 0, width: 190, height: 190))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import AsyncDisplayKit
|
||||
|
||||
public class StackLayout: ASDisplayNode, ASPlayground {
|
||||
public let titleNode = ASTextNode()
|
||||
public let subtitleNode = ASTextNode()
|
||||
|
||||
override public init() {
|
||||
super.init()
|
||||
backgroundColor = .white
|
||||
|
||||
automaticallyManagesSubnodes = true
|
||||
setupNodes()
|
||||
}
|
||||
|
||||
private func setupNodes() {
|
||||
titleNode.backgroundColor = .blue
|
||||
titleNode.attributedText = NSAttributedString.attributedString(string: "Headline!", fontSize: 14, color: .white, firstWordColor: nil)
|
||||
|
||||
subtitleNode.backgroundColor = .yellow
|
||||
subtitleNode.attributedText = NSAttributedString(string: "Lorem ipsum dolor sit amet, sed ex laudem utroque meliore, at cum lucilius vituperata. Ludus mollis consulatu mei eu, esse vocent epicurei sed at. Ut cum recusabo prodesset. Ut cetero periculis sed, mundi senserit est ut. Nam ut sonet mandamus intellegebat, summo voluptaria vim ad.")
|
||||
}
|
||||
|
||||
// This is used to expose this function for overriding in extensions
|
||||
override public func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
|
||||
return ASLayoutSpec()
|
||||
}
|
||||
|
||||
public func show() {
|
||||
display(inRect: .zero)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import UIKit
|
||||
import Foundation
|
||||
|
||||
extension UIColor {
|
||||
|
||||
static func darkBlueColor() -> UIColor {
|
||||
return UIColor(red: 18.0/255.0, green: 86.0/255.0, blue: 136.0/255.0, alpha: 1.0)
|
||||
}
|
||||
|
||||
|
||||
static func lightBlueColor() -> UIColor {
|
||||
return UIColor(red: 0.0, green: 122.0/255.0, blue: 1.0, alpha: 1.0)
|
||||
}
|
||||
|
||||
static func duskColor() -> UIColor {
|
||||
return UIColor(red: 255/255.0, green: 181/255.0, blue: 68/255.0, alpha: 1.0)
|
||||
}
|
||||
|
||||
static func customOrangeColor() -> UIColor {
|
||||
return UIColor(red: 40/255.0, green: 43/255.0, blue: 53/255.0, alpha: 1.0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension NSAttributedString {
|
||||
|
||||
static func attributedString(string: String, fontSize size: CGFloat, color: UIColor?, firstWordColor: UIColor?) -> NSAttributedString {
|
||||
let attributes = [NSForegroundColorAttributeName: color ?? UIColor.black,
|
||||
NSFontAttributeName: UIFont.boldSystemFont(ofSize: size)]
|
||||
|
||||
let attributedString = NSMutableAttributedString(string: string, attributes: attributes)
|
||||
|
||||
if let firstWordColor = firstWordColor {
|
||||
let nsString = string as NSString
|
||||
let firstSpaceRange = nsString.rangeOfCharacter(from: NSCharacterSet.whitespaces)
|
||||
let firstWordRange = NSMakeRange(0, firstSpaceRange.location)
|
||||
attributedString.addAttribute(NSForegroundColorAttributeName, value: firstWordColor, range: firstWordRange)
|
||||
}
|
||||
|
||||
return attributedString
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='6.0' target-platform='ios' display-mode='rendered' timelineScrubberEnabled='true'>
|
||||
<pages>
|
||||
<page name='Index'/>
|
||||
<page name='StackLayout'/>
|
||||
<page name='PhotoWithInsetTextOverlay'/>
|
||||
<page name='PhotoWithOutsetIconOverlay'/>
|
||||
<page name='HorizontalStackWithSpacer'/>
|
||||
</pages>
|
||||
</playground>
|
||||
Reference in New Issue
Block a user