More Related Content
Similar to 미려한 UI/UX를 위한 여정 (20)
미려한 UI/UX를 위한 여정
- 8. • 1 center (0, 0) -> center (40, 0)
(0, 0) (40, 0)
- 9. • 1 center (0, 0) -> center (40, 0)
(0, 0) (40, 0)
vCircle.center = CGPoint.init(x: 0, y: 0)
UIView.animate(withDuration: 1) {
vCircle.center = CGPoint.init(x: 40, y: 0)
}
- 10. • 1 center (0, 0) -> center(40, 0)
(0, 0) (40, 0)
vCircleCenterX.constant = 40
UIView.animate(withDuration: 1) {
vCircle.superview?.layoutIfNeeded()
}
- 14. (100, 100)
let circlePath = UIBezierPath(
arcCenter: CGPoint(x: 100, y: 100),
radius: 50,
startAngle: 0,
endAngle: .pi * 2,
clockwise: true
)
let animation = CAKeyframeAnimation(
keyPath: #keyPath(CALayer.position)
)
animation.duration = 1
animation.path = circlePath.cgPath
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
vCircle.layer.add(animation, forKey: nil)
(100, 50)
- 15. • 3 center (0, 0) -> center (40, 0)
• 1.5 alpha 0.9 -> alpha 0.3
(0, 0) (40, 0)
- 16. vCircle.center = CGPoint(x: 0, y: 0)
vCircle.alpha = 1
UIView.animate(withDuration: 1.5, animations: {
vCircle.center = CGPoint(x: 20, y: 0)
vCircle.alpha = 0.3
}, completion: { _ in
UIView.animate(withDuration: 1.5) {
vCircle.center = CGPoint(x: 40, y: 0)
}
})
- 17. vCircle.center = CGPoint(x: 0, y: 0)
vCircle.alpha = 1
UIView.animate(withDuration: 1.5, animations: {
vCircle.center = CGPoint(x: 20, y: 0)
vCircle.alpha = 0.3
}, completion: { _ in
UIView.animate(withDuration: 1.5) {
vCircle.center = CGPoint(x: 40, y: 0)
}
})
- 18. vCircle.center = CGPoint(x: 0, y: 0)
vCircle.alpha = 1
UIView.animate(withDuration: 3) {
vCircle.center = CGPoint(x: 40, y: 0)
}
UIView.animate(withDuration: 1.5) {
vCircle.alpha = 0
}
- 22. • CADisplayLink
• A timer object that allows your application to
synchronize its drawing to the refresh rate of the
display
- 23. • CADisplayLink
• A timer object that allows your application to
synchronize its drawing to the refresh rate of the
display
•
- 24. vCircle.center = CGPoint(x: 0, y: 0)
vCircle.alpha = 1
UIView.animate(withDuration: 3) {
vCircle.center = CGPoint(x: 40, y: 0)
}
UIView.animate(withDuration: 1.5) {
vCircle.alpha = 0
}
- 25. func aniStart() {
displayLink = CADisplayLink(target: self, selector: #selector(update))
displayLink?.add(to: .main, forMode: .common)
start1 = now() ; start2 = now()
term1 = 3 ; term2 = 1.5
isEnd1 = false; isEnd2 = false
}
@objc func update() { ani1(); ani2() }
func ani1() {
guard !isEnd1 else { return }
let rate = min(1.0, (now() - start1) / term1)
if rate == 1.0 { isEnd1 = true }
vCircle.center = CGPoint(x: 40.0 * rate, y: 0)
}
func ani2() {
guard !isEnd2 else { return }
let rate = min(1.0, (now() - start2) / term2)
if rate == 1.0 { isEnd2 = true }
vCircle.alpha = CGFloat(1.0 - rate)
}
- 27. func aniStart() {
displayLink = CADisplayLink(target: self, selector: #selector(update))
displayLink?.add(to: .main, forMode: .common)
start1 = now() ; start2 = now()
term1 = 3 ; term2 = 1.5
isEnd1 = false; isEnd2 = false
}
@objc func update() { ani1(); ani2() }
func ani1() {
guard !isEnd1 else { return }
let rate = min(1.0, (now() - start1) / term1)
if rate == 1.0 { isEnd1 = true }
vCircle.center = CGPoint(x: 40.0 * rate, y: 0)
}
func ani2() {
guard !isEnd2 else { return }
let rate = min(1.0, (now() - start2) / term2)
if rate == 1.0 { isEnd2 = true }
vCircle.alpha = CGFloat(1.0 - rate)
}
- 28. func aniStart() {
displayLink = CADisplayLink(target: self, selector: #selector(update))
displayLink?.add(to: .main, forMode: .common)
start1 = now() ; start2 = now()
term1 = 3 ; term2 = 1.5
isEnd1 = false; isEnd2 = false
}
@objc func update() { ani1(); ani2() }
func ani1() {
guard !isEnd1 else { return }
let rate = min(1.0, (now() - start1) / term1)
if rate == 1.0 { isEnd1 = true }
vCircle.center = CGPoint(x: 40.0 * rate, y: 0)
}
func ani2() {
guard !isEnd2 else { return }
let rate = min(1.0, (now() - start2) / term2)
if rate == 1.0 { isEnd2 = true }
vCircle.alpha = CGFloat(1.0 - rate)
}
class Item {
typealias Block = (Item) -> Void
static let emptyBlock: Block = { _ in }
var start = 0.0
var term = 0.0
var rate = 0.0
var current = 0.0
var block: Block = Item.emptyBlock
var ended: Block = Item.emptyBlock
var next: Item? = nil
var isStop = false
fileprivate var marked = false
…
}
- 29. func aniStart() {
…
}
@objc func update() {
ani1(); ani2()
}
func ani1() {
guard !isEnd1 else { return }
let rate = min(1.0, (now() - start1) / term1)
if rate == 1.0 { isEnd1 = true }
vCircle.center = CGPoint(x: 40.0 * rate, y: 0)
}
func ani2() {
guard !isEnd2 else { return }
let rate = min(1.0, (now() - start2) / term2)
if rate == 1.0 { isEnd2 = true }
vCircle.alpha = CGFloat(1.0 - rate)
}
- 30. func aniStart() {
…
}
@objc func update() {
ani1(); ani2()
}
func ani1() {
guard !isEnd1 else { return }
let rate = min(1.0, (now() - start1) / term1)
if rate == 1.0 { isEnd1 = true }
vCircle.center = CGPoint(x: 40.0 * rate, y: 0)
}
func ani2() {
guard !isEnd2 else { return }
let rate = min(1.0, (now() - start2) / term2)
if rate == 1.0 { isEnd2 = true }
vCircle.alpha = CGFloat(1.0 - rate)
}
class Looper {
private var items = Collection<Item>()
private var pool = Collection<Item>()
…
fileprivate func loop() {
let c = now()
let _items = items.elements
var cnt = _items.count
var hasRemoveItems = false
while 0 < cnt {
cnt -= 1
let item = _items[cnt]
…
item.rate = { … }()
item.block(item)
…
}
if hasRemoveItems { … }
}
}
- 32. Looper
looper.invoke { (dsl) in
dsl.time = 0.3
dsl.block = { item in
vCircle.alpha = CGFloat(item.rate)
}
}
@discardableResult
func invoke(
_ block: (ItemDSL) -> Void
) -> Sequence {
let dsl = ItemDSL()
block(dsl)
let item = getItem(dsl)
item.start += now()
item.end = item.start + item.term
items.append(item)
sequence.current = item
return sequence
}
- 33. Updater
private var displayLink: CADisplayLink?
func aniStart() {
displayLink = CADisplayLink(target: self, selector: #selector(update))
displayLink?.add(to: .main, forMode: .common)
…
}
@objc func update() { ... }
- 34. Updater
class Updater {
private var displayLink: CADisplayLink?
fileprivate var loopers = [Looper]()
func start() {
displayLink = CADisplayLink(
target: self, selector: #selector(update)
)
displayLink?.add(to: .main, forMode: .common)
}
…
@objc func update() { loopers.forEach { $0.loop() } }
}
- 35. Looper
looper.invoke { dsl in
dsl.time = 3
dsl.block = { item in
self.vCircle.center = CGPoint(x: 40.0 * item.rate, y: 0)
}
}
looper.invoke { dsl in
dsl.time = 1.5
dsl.block = { item in
self.vCircle.alpha = CGFloat(1.0 - item.rate)
}
}
10
- 46. func fetch1(completion: @escaping (Response) -> Void) {
Alamofire.request(“api/fetch1").response { completion($0.response!) }
}
…
fetch1 { response1 in
fetch2 { response2 in
fetch3 { response3 in
section3.render(with: response3)
}
section2.render(with: response2)
}
section1.render(with: response1)
}
- 47. var res1: Response!; var res2: Response!; var res3: Response!
func fetchAll() {
fetch1 { r in res1 = r; render(); }
fetch2 { r in res2 = r; render(); }
fetch3 { r in res3 = r; render(); }
}
func render() {
guard let res1 = res1, let res2 = res2, let res3 = res3 else { return }
section1.render(with: res1)
section2.render(with: res2)
section3.render(with: res3)
}
- 48. var res1: Response!; var res2: Response!; var res3: Response!
func fetchAll() {
fetch1 { r in res1 = r; render(); }
fetch2 { r in res2 = r; render(); }
fetch3 { r in res3 = r; render(); }
}
func render() {
guard let res1 = res1, let res2 = res2, let res3 = res3 else { return }
section1.render(with: res1)
section2.render(with: res2)
section3.render(with: res3)
}
- 49. var res1: Response!
looper.invoke { dsl in
fetch1 { r in res1 = r }
dsl.isInfinity = true
dsl.block = { item in
if res1 != nil { section1.render(with: res1); item.isStop = true }
}
}
- 50. var res1: Response!; var res2: Response!
looper.invoke { dsl in
fetch1 { r in res1 = r }
dsl.isInfinity = true
dsl.block = { item in
if res1 != nil { section1.render(with: res1); item.isStop = true }
}
}.next { dsl in
fetch2 { r in res2 = r }
dsl.isInfinity = true
dsl.block = { item in
if res2 != nil { section2.render(with: res2); item.isStop = true }
}
}
- 54. var res1: Response!; var res2: Response!
looper.invoke { dsl in
fetch1 { r in res1 = r }
dsl.isInfinity = true
dsl.block = { item in
if res1 != nil {
section1.render(with: res1);
item.isStop = true
}
}
}.next { dsl in
fetch2 { r in res2 = r }
dsl.isInfinity = true
dsl.block = { item in
if res2 != nil {
section2.render(with: res2);
item.isStop = true
}
}
}
Flow()
.async { sync in
fetch1 { r in
sync { section1.render(with: r) }
}
}
.async { sync in
fetch2 { r in
sync { section2.render(with: r) }
}
}
.start()
- 55. class Flow {
private class Block {
static let TypeAsync = “async"
var type: String
let body: Any
init(type: String, body: Any) {
self.type = type
self.body = body
}
}
typealias VoidClosure = () -> Void
typealias Sync = (@escaping VoidClosure) -> Void
typealias Async = (@escaping Sync) -> Void
private var blocks = [Block]()
private var seq: Looper.Sequence?
…
}
- 56. class Flow {
private class Block { … }
typealias VoidClosure = () -> Void
typealias Sync = (@escaping VoidClosure) -> Void
typealias Async = (@escaping Sync) -> Void
private var blocks = [Block]()
privatevar seq: Looper.Sequence?
@discardableResult
func async(body: @escaping Async) -> Flow {
blocks.append(Block(type: Block.TypeAsync, body: body))
return self
}
func start() {
…
_start()
}
…
}
private func _start() {
while blocks.count > 0 {
let block = blocks.removeFirst()
switch block.type {
case Block.TypeAsync:
let body = block.body as! Async
let dslBlock = getDSLBlock(body)
seq = seq?.next(dslBlock)
?? looper.invoke(dslBlock)
default: break
}
}
}
- 57. class Flow {
…
typealias VoidClosure = () -> Void
typealias Sync = (@escaping VoidClosure) -> Void
typealias Async = (@escaping Sync) -> Void
…
private func getDSLBlock(
_ async: @escaping Async
) -> (Looper.Looper.ItemDSL) -> Void {
{ dsl in
var completion: VoidClosure?
async({ c in completion = c })
dsl.isInfinity = true
dsl.block = { item in
if completion != nil {
completion?(); item.isStop = true
}
}
}
}
Flow()
.async { sync in
fetch1 { r in
sync { section1.render(with: r) }
}
}
.async { sync in
fetch2 { r in
sync { section2.render(with: r) }
}
}
.start()
- 58. Flow - async
Flow()
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.start()
- 59. Flow - async
Flow()
.async { sync in sync { indicator.show() } }
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.async { sync in sync { indicator.hide() } }
.start()
- 60. Flow - sync
Flow()
.
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.
.start()
.async { sync in sync { indicator.show() }
}
.async { sync in sync { indicator.hide() }
}
- 61. Flow - sync
class Flow {
private class Block {
static let TypeSync = "sync"
…
}
….
@discardableResult
func sync(body: @escaping Sync) -> Flow {
blocks.append(Block(type: Block.TypeSync, body: body))
return self
}
…
}
- 62. private func _start() {
while blocks.count > 0 {
let block = blocks.removeFirst()
switch block.type {
case Block.TypeAsync:
let body = block.body as! Async
let dslBlock = getDSLBlock(body)
seq = seq?.next(dslBlock) ?? looper.invoke(dslBlock)
case Block.Sync:
let body = block.body as! VoidClosure
let nBody: Async = { $0(body) }
blocks.insert(
Flow.Block(type: Block.TypeAsync, body: nBody), at: 0
)
default: break
}
}
}
- 63. Flow()
.sync { indicator.show() }
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.sync { indicator.hide() }
.start()
200ms + 15ms800ms + 15ms800ms + 15ms + 15ms800ms + 15ms + 15ms + 15ms
Flow - sync
15ms=
- 64. Flow - pause
Flow()
.sync { indicator.show(); after(delay: 2) { indicator.hide() } }
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.start()
- 65. Flow - pause
Flow()
.sync { indicator.show() }
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.sync { indicator.hide() }
.start()
- 66. Flow - pause
var started: TimeInterval!
Flow()
.sync { indicator.show(); started = now() }
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()
- 67. Flow - pause
private class Block {
…
static let TypePause = "pause"
var delay: () -> TimeInterval
init(
type: String,
body: Any,
delay: @escaping () -> TimeInterval = { 0 }
) {
…
self.delay = delay
}
}
- 68. Flow - pause
class Flow {
…
@discardableResult
func pause(
duration delay: @escaping () -> TimeInterval,
body: @escaping VoidClosure = Block.EmptyBody
) -> Flow {
blocks.append(Flow.Block(type: Block.TypePause, body: body,
delay: delay))
return self
}
…
}
- 69. private func getDSLBlock(
delay: @escaping () -> TimeInterval = { 0 },
_ body: @escaping Async
) -> (Looper.Looper.ItemDSL) -> Void {
{ dsl in
var waiting: Double!
var started: Double!
var completion: VoidClosure?
body({ c in completion = c })
dsl.isInfinity = true
dsl.block = { item in
if started == nil { started = item.current; waiting = delay() }
if completion != nil && item.current - started >= waiting {
completion?(); item.isStop = true
}
}
}
}
private func getDSLBlock(
delay: @escaping () -> TimeInterval = { 0 },
_ body: @escaping Async
) -> (Looper.Looper.ItemDSL) -> Void {
{ dsl in
var waiting: Double!
var started: Double!
var completion: VoidClosure?
body({ c in completion = c })
dsl.isInfinity = true
dsl.block = { item in
if started == nil { started = item.current; waiting = delay() }
if completion != nil {
completion?(); item.isStop = true
}
}
}
}
private func getDSLBlock(
delay: @escaping () -> TimeInterval = { 0 },
_ body: @escaping Async
) -> (Looper.Looper.ItemDSL) -> Void {
{ dsl in
var waiting: Double!
var started: Double!
var completion: VoidClosure?
body({ c in completion = c })
dsl.isInfinity = true
dsl.block = { item in
if completion != nil {
completion?(); item.isStop = true
}
}
}
}
private func getDSLBlock(
delay: @escaping () -> TimeInterval = { 0 },
_ body: @escaping Async
) -> (Looper.Looper.ItemDSL) -> Void {
{ dsl in
var completion: VoidClosure?
body({ c in completion = c })
dsl.isInfinity = true
dsl.block = { item in
if completion != nil {
completion?(); item.isStop = true
}
}
}
}
private func getDSLBlock(
_ body: @escaping Async
) -> (Looper.Looper.ItemDSL) -> Void {
{ dsl in
var completion: VoidClosure?
body({ c in completion = c })
dsl.isInfinity = true
dsl.block = { item in
if completion != nil {
completion?(); item.isStop = true
}
}
}
}
- 70. private func _start() {
while blocks.count > 0 {
let block = blocks.removeFirst()
switch block.type {
…
case Block.Sync:
let body = block.body as! VoidClosure
let nBody: Async = { $0(body) }
blocks.insert(Flow.Block(type: Block.TypeAsync, body: nBody), at: 0)
case Block.Pause:
let body = block.body as! VoidClosure
let nBody: Async = { $0(body) }
blocks.insert(
Flow.Block(type: Block.TypeAsync, body: nBody, delay: block.delay), at: 0
)
default: break
}
}
}
- 71. private func _start() {
while blocks.count > 0 {
let block = blocks.removeFirst()
switch block.type {
…
case Block.Sync, Block.Pause:
let body = block.body as! VoidClosure
let nBody: Async = { $0(body) }
blocks.insert(
Flow.Block(type: Block.TypeAsync, body: nBody, delay: block.delay), at: 0
)
default: break
}
}
}
- 72. private func _start() {
while blocks.count > 0 {
let block = blocks.removeFirst()
switch block.type {
case Block.TypeAsync:
let delay = block.delay
let body = block.body as! Async
let dslBlock = getDSLBlock(delay: delay, body)
seq = seq?.next(dslBlock) ?? looper.invoke(dslBlock)
case Block.Sync, Block.Pause:
let body = block.body as! VoidClosure
let nBody: Async = { $0(body) }
blocks.insert(
Flow.Block(type: Block.TypeAsync, body: nBody, delay: block.delay), at: 0
)
default: break
}
}
}
- 73. Flow - bundle
var started: TimeInterval!
Flow()
.sync { indicator.show(); started = now() }
.async { sync in fetch1 { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()
- 74. Flow - bundle
var started: TimeInterval!
var k1: String!; var k2: String!;
Flow()
.sync { indicator.show(); started = now() }
.async { sync in fetchKey1 { r in sync { key1 = r } } }
.async { sync in fetchKey2 { r in sync { key2 = r) } } }
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()
- 75. Flow - bundle
Flow()
.sync { indicator.show(); started = now() }
.async { sync in fetchKey1 { r in sync { key1 = r } } }
.async { sync in fetchKey2 { r in sync { key2 = r) } } }
.sync {
Flow() .async { sync in
fetch1(k1, k2) { r in sync { section1.render(with: r) } }
} …
.start()
}
.start()
- 76. Flow - bundle
Flow()
.sync { indicator.show(); started = now() }
.bundle { Flow().async { … }.async { … } }
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()
- 77. Flow - bundle
class Flow {
private class Block {
static let TypeBundle = “bundle"
…
}
typealias Bundle = () -> Flow
…
@discardableResult
func bundle(body: @escaping Bundle) -> Flow {
blocks.append(Block(type: Block.TypeBundle, body: body))
return self
}
}
- 78. private func _start() {
var sub: Flow?
knitting: while blocks.count > 0 {
let block = blocks.removeFirst()
switch block.type {
…
case Block.TypeBundle:
let body = block.body as! Bundle
sub = body()
break knitting
default: break
}
}
…
}
- 79. private func _start() {
var sub: Flow?
…
if let sub = sub {
if blocks.count > 0 {
sub.blocks.append(
Flow.Block(
type: Block.TypeBundle,
body: { () -> Flow in self.seq = nil; return self }
)
)
}
if seq?.current != nil { seq?.current?.ended = { _ in sub._start() } }
else { sub._start() }
}
}
- 80. Flow()
.sync {
indicator.show(); started = now()
}
.bundle {
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
}
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()
- 81. Flow()
.sync {
indicator.show(); started = now()
}
.bundle {
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
}
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()
var flow1: Flow
Flow()
.sync {
indicator.show(); started = now()
}
.bundle {
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
}
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
- 82. var flow1: Flow
flow1 = Flow()
flow1.sync {
indicator.show(); started = now()
}
.bundle {
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
}
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
- 83. var flow1: Flow
flow1 = Flow()
flow1.sync {
indicator.show(); started = now()
}
.bundle {
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
}
}
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
- 84. var flow1: Flow
flow1 = Flow()
flow1.sync {
indicator.show(); started = now()
}
.bundle {
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
}
}
- 85. var flow1: Flow
flow1 = Flow()
flow1.sync {
indicator.show(); started = now()
}
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
}
- 86. var flow1: Flow
flow1 = Flow()
flow1.sync {
indicator.show(); started = now()
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
}
.start()
}
- 87. var flow1: Flow
flow1 = Flow()
flow1.sync {
indicator.show(); started = now()
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
}
.start()
}
- 88. var flow1: Flow
flow1 = Flow()
flow1.sync {
indicator.show(); started = now()
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
}
.start()
}
- 89. var flow1: Flow
flow1 = Flow()
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
}
- 90. var flow1: Flow
flow1 = Flow()
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
.bundle {
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
}
- 91. var flow1: Flow
flow1 = Flow()
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
- 92. Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r
flow1
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()
} } }
- 93. private func _start() {
var sub: Flow?
…
if let sub = sub {
if blocks.count > 0 {
sub.blocks.append(
Flow.Block(
type: Block.TypeBundle,
body: { () -> Flow in self.seq = nil; return self }
)
)
}
if seq?.current != nil { seq?.current?.ended = { _ in sub._start() } }
else { sub._start() }
}
}
- 94. Flow()
.sync {
indicator.show(); started = now()
}
.bundle {
Flow()
.async { sync in fetchKey1 { r in sync { k1 = r } } }
.async { sync in fetchKey2 { r in sync { k2 = r } } }
}
.async { sync in fetch1(k1, k2) { r in sync { section1.render(with: r) } } }
.async { sync in fetch2 { r in sync { section2.render(with: r) } } }
.async { sync in fetch3 { r in sync { section3.render(with: r) } } }
.pause(duration: { 2 - min(2, now() - started) }) {
indicator.hide()
}
.start()