[ASCornerLayoutSpec] New layout spec class for declarative corner element layout. (#657)

* Add new layout spec class with snapshot testing. Update examples and CHANGELOG.md

* Code review updates.

* Open curly bracket in a new line.
This commit is contained in:
huang-kun
2017-11-24 21:45:59 +08:00
committed by Huy Nguyen
parent b2539d3531
commit e4b2c05c21
42 changed files with 910 additions and 16 deletions

View File

@@ -143,3 +143,140 @@ class FlexibleSeparatorSurroundingContent : LayoutExampleNode {
return "try rotating me!"
}
}
class CornerLayoutSample : PhotoWithOutsetIconOverlay {
let photoNode1 = ASImageNode()
let photoNode2 = ASImageNode()
let dotNode = ASImageNode()
let badgeTextNode = ASTextNode()
let badgeImageNode = ASImageNode()
struct ImageSize {
static let avatar = CGSize(width: 100, height: 100)
static let icon = CGSize(width: 26, height: 26)
}
struct ImageColor {
static let avatar = UIColor.lightGray
static let icon = UIColor.red
}
required init() {
super.init()
let avatarImage = UIImage.draw(size: ImageSize.avatar, fillColor: ImageColor.avatar) { () -> UIBezierPath in
return UIBezierPath(roundedRect: CGRect(origin: CGPoint.zero, size: ImageSize.avatar), cornerRadius: ImageSize.avatar.width / 20)
}
let iconImage = UIImage.draw(size: ImageSize.icon, fillColor: ImageColor.icon) { () -> UIBezierPath in
return UIBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: ImageSize.icon))
}
photoNode1.image = avatarImage
photoNode2.image = avatarImage
dotNode.image = iconImage
badgeTextNode.attributedText = NSAttributedString.attributedString(string: " 999+ ", fontSize: 20, color: .white)
badgeImageNode.image = UIImage.as_resizableRoundedImage(withCornerRadius: 12, cornerColor: .clear, fill: .red)
}
override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
photoNode.style.preferredSize = ImageSize.avatar
iconNode.style.preferredSize = ImageSize.icon
let badgeSpec = ASBackgroundLayoutSpec(child: badgeTextNode, background: badgeImageNode)
let cornerSpec1 = ASCornerLayoutSpec(child: photoNode1, corner: dotNode, location: .topRight)
let cornerSpec2 = ASCornerLayoutSpec(child: photoNode2, corner: badgeSpec, location: .topRight)
let cornerSpec3 = ASCornerLayoutSpec(child: photoNode, corner: iconNode, location: .topRight)
cornerSpec1.offset = CGPoint(x: -3, y: 3)
let stackSpec = ASStackLayoutSpec.vertical()
stackSpec.spacing = 40
stackSpec.children = [cornerSpec1, cornerSpec2, cornerSpec3]
return stackSpec
}
override class func title() -> String {
return "Declarative way for Corner image Layout"
}
override class func descriptionTitle() -> String? {
return nil
}
}
class UserProfileSample : LayoutExampleNode {
let badgeNode = ASImageNode()
let avatarNode = ASImageNode()
let usernameNode = ASTextNode()
let subtitleNode = ASTextNode()
struct ImageSize {
static let avatar = CGSize(width: 44, height: 44)
static let badge = CGSize(width: 15, height: 15)
}
struct ImageColor {
static let avatar = UIColor.lightGray
static let badge = UIColor.red
}
required init() {
super.init()
avatarNode.image = UIImage.draw(size: ImageSize.avatar, fillColor: ImageColor.avatar) { () -> UIBezierPath in
return UIBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: ImageSize.avatar))
}
badgeNode.image = UIImage.draw(size: ImageSize.badge, fillColor: ImageColor.badge) { () -> UIBezierPath in
return UIBezierPath(ovalIn: CGRect(origin: CGPoint.zero, size: ImageSize.badge))
}
makeSingleLine(for: usernameNode, with: "Hello world", fontSize: 17, textColor: .black)
makeSingleLine(for: subtitleNode, with: "This is a long long subtitle, with a long long appended string.", fontSize: 14, textColor: .lightGray)
}
private func makeSingleLine(for node: ASTextNode, with text: String, fontSize: CGFloat, textColor: UIColor) {
node.attributedText = NSAttributedString.attributedString(string: text, fontSize: fontSize, color: textColor)
node.maximumNumberOfLines = 1
}
override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) -> ASLayoutSpec {
let avatarBox = ASCornerLayoutSpec(child: avatarNode, corner: badgeNode, location: .bottomRight)
avatarBox.offset = CGPoint(x: -6, y: -6)
let textBox = ASStackLayoutSpec.vertical()
textBox.justifyContent = .spaceAround
textBox.children = [usernameNode, subtitleNode]
let profileBox = ASStackLayoutSpec.horizontal()
profileBox.spacing = 10
profileBox.children = [avatarBox, textBox]
// Apply text truncation
let elems: [ASLayoutElement] = [usernameNode, subtitleNode, textBox, profileBox]
for elem in elems {
elem.style.flexShrink = 1
}
let insetBox = ASInsetLayoutSpec(
insets: UIEdgeInsets(top: 120, left: 20, bottom: CGFloat.infinity, right: 20),
child: profileBox
)
return insetBox
}
override class func title() -> String {
return "Common user profile layout."
}
override class func descriptionTitle() -> String? {
return "For corner image layout and text truncation."
}
}