Last active
July 22, 2020 08:32
-
-
Save wiiale/43d0dda17d40abea48866403d4961213 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: A UIKit based Playground for presenting user interface | |
import UIKit | |
import PlaygroundSupport | |
enum SkyBehavior: String { | |
case clickSky = "clickSky" | |
case clickSun = "clickSun" | |
case clickSunspot = "clickSunspot" | |
} | |
extension UIResponder { | |
@objc func routerEvent(name: String, userInfo: [AnyHashable: Any]?) { | |
next?.routerEvent(name: name, userInfo: userInfo) | |
} | |
} | |
class SkyView: UIView { | |
let sunView = SunView(frame: .sun) | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
backgroundColor = .blue | |
addSubview(sunView) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
routerEvent(name: SkyBehavior.clickSky.rawValue, userInfo: nil) | |
} | |
} | |
class SunView: UIView { | |
let spotView = SunspotView(frame: .sunspot) | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
backgroundColor = .red | |
addSunlight() | |
addSubview(spotView) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
routerEvent(name: SkyBehavior.clickSun.rawValue, userInfo: nil) | |
} | |
override func routerEvent(name: String, userInfo: [AnyHashable : Any]?) { | |
super.routerEvent(name: name, userInfo: userInfo) | |
if name == SkyBehavior.clickSunspot.rawValue { | |
routerEvent(name: SkyBehavior.clickSun.rawValue, userInfo: nil) | |
} | |
} | |
} | |
class SunspotView: UIView { | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
backgroundColor = .black | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
routerEvent(name: SkyBehavior.clickSunspot.rawValue, userInfo: ["sunspotId": 10]) | |
} | |
} | |
class SkyViewController: UIViewController { | |
override func loadView() { | |
self.view = SkyView() | |
} | |
override func routerEvent(name: String, userInfo: [AnyHashable : Any]?) { | |
guard let event = SkyBehavior(rawValue: name) else { return } | |
switch event { | |
case .clickSky: print("[Sky] click sky") | |
case .clickSun: print("[Sky] click sun") | |
case .clickSunspot: | |
print("[Sky] click sun spot") | |
} | |
} | |
} | |
fileprivate extension SunView { | |
func addSunlight() { | |
layer.shadowColor = UIColor.red.cgColor | |
layer.shadowRadius = 10 | |
layer.shadowOpacity = 0.8 | |
layer.shadowPath = UIBezierPath(rect: .sunlight).cgPath | |
layer.shouldRasterize = true | |
layer.rasterizationScale = UIScreen.main.scale | |
} | |
} | |
// Colors | |
fileprivate extension UIColor { | |
convenience init(r: UInt32, g: UInt32, b: UInt32) { | |
self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: 1.0) | |
} | |
static var red: UIColor { return .init(r: 236, g: 67, b: 84) } | |
static var blue: UIColor { return .init(r: 44, g: 110, b: 179) } | |
static var green: UIColor { return .init(r: 71, g: 180, b: 90) } | |
static var black: UIColor { return .init(r: 46, g: 36, b: 35) } | |
static var random: UIColor { | |
return .init(r: arc4random() % 255, g: arc4random() % 255, b: arc4random() % 255) | |
} | |
} | |
// LayoutConstants | |
fileprivate extension CGRect { | |
static var sun: CGRect { | |
return CGRect(x: 50, y: 50, width: 100, height: 100) | |
} | |
static var sunlight: CGRect { | |
return CGRect(x: -10, y: -10, width: 120, height: 120) | |
} | |
static var sunspot: CGRect { | |
return CGRect(x: 20, y: 20, width: 10, height: 10) | |
} | |
} | |
// Present the view controller in the Live View window | |
PlaygroundPage.current.liveView = SkyViewController() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: A UIKit based Playground for presenting user interface | |
import UIKit | |
import PlaygroundSupport | |
public protocol ResponderChainEventType {} | |
public protocol ResponderChainType { | |
func router<Event>(event: Event) where Event : ResponderChainEventType | |
} | |
extension ResponderChainType where Self: UIResponder { | |
public func router<Event>(event: Event) where Event : ResponderChainEventType { | |
// Responder handler | |
if let n = next as? SkyViewController { | |
n.router(event: event) | |
} else { | |
next?.router(event: event) | |
} | |
} | |
} | |
extension UIResponder: ResponderChainType {} | |
//: Custom Events | |
enum SkyBehavior: ResponderChainEventType { | |
case clickSky | |
case clickSun | |
case clickSunspot(id: Int) | |
} | |
//: Custom view | |
class SkyView: UIView { | |
let sunView = SunView(frame: .sun) | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
backgroundColor = .blue | |
addSubview(sunView) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
router(event: SkyBehavior.clickSky) | |
} | |
} | |
class SunView: UIView { | |
let spotView = SunspotView(frame: .sunspot, id: 1) | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
backgroundColor = .red | |
addSunlight() | |
addSubview(spotView) | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
router(event: SkyBehavior.clickSun) | |
} | |
} | |
class SunspotView: UIView { | |
let id: Int | |
init(frame: CGRect, id: Int) { | |
self.id = id | |
super.init(frame: frame) | |
backgroundColor = .black | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { | |
router(event: SkyBehavior.clickSunspot(id: id)) | |
} | |
} | |
class SkyViewController: UIViewController { | |
override func loadView() { | |
self.view = SkyView() | |
} | |
func router<Event>(event: Event) where Event : ResponderChainEventType { | |
guard let e = event as? SkyBehavior else { return } | |
switch e { | |
case .clickSky: print("[Sky] click sky") | |
case .clickSun: print("[Sky] click sun") | |
case .clickSunspot(let sunspotId): print("[Sky] click sunspot - id: \(sunspotId)") | |
} | |
} | |
} | |
fileprivate extension SunView { | |
func addSunlight() { | |
layer.shadowColor = UIColor.red.cgColor | |
layer.shadowRadius = 10 | |
layer.shadowOpacity = 0.8 | |
layer.shadowPath = UIBezierPath(rect: .sunlight).cgPath | |
layer.shouldRasterize = true | |
layer.rasterizationScale = UIScreen.main.scale | |
} | |
} | |
// Colors | |
fileprivate extension UIColor { | |
convenience init(r: UInt32, g: UInt32, b: UInt32) { | |
self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: 1.0) | |
} | |
static var red: UIColor { return .init(r: 236, g: 67, b: 84) } | |
static var blue: UIColor { return .init(r: 44, g: 110, b: 179) } | |
static var green: UIColor { return .init(r: 71, g: 180, b: 90) } | |
static var black: UIColor { return .init(r: 46, g: 36, b: 35) } | |
static var random: UIColor { | |
return .init(r: arc4random() % 255, g: arc4random() % 255, b: arc4random() % 255) | |
} | |
} | |
// LayoutConstants | |
fileprivate extension CGRect { | |
static var sun: CGRect { | |
return CGRect(x: 50, y: 50, width: 100, height: 100) | |
} | |
static var sunlight: CGRect { | |
return CGRect(x: -10, y: -10, width: 120, height: 120) | |
} | |
static var sunspot: CGRect { | |
return CGRect(x: 20, y: 20, width: 10, height: 10) | |
} | |
} | |
// Present the view controller in the Live View window | |
PlaygroundPage.current.liveView = SkyViewController() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment