Beginning work on header view

This commit is contained in:
Charles Magahern
2015-12-30 18:47:13 -08:00
parent 00fcca6893
commit 29dec42b20
21 changed files with 592 additions and 43 deletions
@@ -25,6 +25,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask
{
return UIInterfaceOrientationMask.Portrait
return UIInterfaceOrientationMask.Landscape
}
}
@@ -0,0 +1,16 @@
//
// ArcadeMachinesViewController.swift
// XIONControlPanel
//
// Created by Charles Magahern on 12/30/15.
// Copyright © 2015 XION. All rights reserved.
//
import UIKit
class ArcadeMachinesViewController: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
}
}
@@ -9,7 +9,9 @@
import UIKit
class MainViewController: UIViewController {
private var _backgroundController: BackgroundViewController = BackgroundViewController()
private var _visualizationController: VisualizationViewController = VisualizationViewController()
private var _machinesController: ArcadeMachinesViewController = ArcadeMachinesViewController()
private var _headerView: HeaderView = HeaderView()
// MARK: Overrides
@@ -19,22 +21,13 @@ class MainViewController: UIViewController {
self.view.backgroundColor = UIColor.blackColor()
self.addChildViewController(_backgroundController)
self.view.addSubview(_backgroundController.view)
self.addChildViewController(_visualizationController)
self.view.addSubview(_visualizationController.view)
let doubleTapGR = UITapGestureRecognizer(target: self, action: Selector("_handleDoubleFingerTap:"))
doubleTapGR.numberOfTouchesRequired = 2
self.view.addGestureRecognizer(doubleTapGR)
self.addChildViewController(_machinesController)
self.view.addSubview(_machinesController.view)
let singleTapGR = UITapGestureRecognizer(target: self, action: Selector("_handleSingleFingerTap:"))
singleTapGR.numberOfTouchesRequired = 1
singleTapGR.requireGestureRecognizerToFail(doubleTapGR)
self.view.addGestureRecognizer(singleTapGR)
}
override func prefersStatusBarHidden() -> Bool
{
return true
self.view.addSubview(_headerView)
}
override func viewDidLayoutSubviews()
@@ -42,19 +35,50 @@ class MainViewController: UIViewController {
super.viewDidLayoutSubviews()
let bounds = self.view.bounds
_backgroundController.view.frame = bounds
let headerBounds = CGRect(
x: 0.0,
y: 0.0,
width: bounds.size.width,
height: rint(bounds.size.height / 10.0)
)
let bodyBounds = CGRect(
x: 0.0,
y: CGRectGetMaxY(headerBounds),
width: bounds.size.width,
height: bounds.size.height - headerBounds.size.height
)
_headerView.frame = headerBounds
let visualizationFrame = CGRect(
x: bodyBounds.origin.x,
y: bodyBounds.origin.y,
width: rint((5.0 / 8.0) * bodyBounds.size.width),
height: bodyBounds.size.height
)
_visualizationController.view.frame = visualizationFrame
let machinesControllerFrame = CGRect(
x: CGRectGetMaxX(visualizationFrame),
y: bodyBounds.origin.y,
width: bodyBounds.size.width - visualizationFrame.size.width,
height: bodyBounds.size.height
)
_machinesController.view.frame = machinesControllerFrame
}
// MARK: Internal
internal func _handleSingleFingerTap(gestureRecognizer: UITapGestureRecognizer)
override func viewDidAppear(animated: Bool)
{
let randomPercentage = Float(arc4random()) / Float(UInt32.max)
_backgroundController.setPercentActivated(randomPercentage, animated: true)
_headerView.beginAnimating()
}
internal func _handleDoubleFingerTap(gestureRecognizer: UITapGestureRecognizer)
override func viewDidDisappear(animated: Bool)
{
_backgroundController.setPercentActivated(0.0, animated: true)
_headerView.stopAnimating()
}
override func prefersStatusBarHidden() -> Bool
{
return true
}
}
@@ -1,5 +1,5 @@
//
// BackgroundViewController.swift
// VisualizationViewController.swift
// XIONControlPanel
//
// Created by Charles Magahern on 12/29/15.
@@ -12,9 +12,9 @@ import GLKit
import SceneKit
import UIKit
let π = Float(M_PI)
let π = CGFloat(M_PI)
class BackgroundViewController: UIViewController {
class VisualizationViewController: UIViewController {
private var _scene: SCNScene = SCNScene()
private var _sceneView: SCNView?
private var _cameraNode: SCNNode = SCNNode()
@@ -34,7 +34,6 @@ class BackgroundViewController: UIViewController {
view.backgroundColor = UIColor.blackColor()
view.scene = _scene
view.allowsCameraControl = false
view.showsStatistics = true
_sceneView = view
self.view = view
@@ -88,7 +87,7 @@ class BackgroundViewController: UIViewController {
let ry = Float(arc4random()) / Float(UInt32.max)
let rz = Float(arc4random()) / Float(UInt32.max)
let rotAxis = SCNVector3Make(rx, ry, rz)
let rotCoeff = Float(arc4random() % 2 == 0 ? -1.0 : 1.0)
let rotCoeff = CGFloat(arc4random() % 2 == 0 ? -1.0 : 1.0)
let rotAngle = CGFloat(rotCoeff * π / 4.0)
let rotAction = SCNAction.rotateByAngle(rotAngle, aroundAxis: rotAxis, duration: 0.8)
@@ -108,7 +107,7 @@ class BackgroundViewController: UIViewController {
let camera = SCNCamera()
_cameraNode.camera = camera
_cameraNode.position = SCNVector3Make(0.0, 0.0, 50.0)
_cameraNode.position = SCNVector3Make(0.0, 0.0, 30.0)
_scene.rootNode.addChildNode(_cameraNode)
let centerNode = SCNNode()
@@ -136,10 +135,10 @@ class BackgroundViewController: UIViewController {
{
_cublets.removeAll()
let sz = Float(BackgroundViewController.cubletsSize)
let dim = BackgroundViewController.cubletsDimensions
let sz = Float(VisualizationViewController.cubletsSize)
let dim = VisualizationViewController.cubletsDimensions
let dimf = Float(dim)
let spacing = Float(BackgroundViewController.cubletsSpacing)
let spacing = Float(VisualizationViewController.cubletsSpacing)
let volume = (dimf * sz) + ((dimf - 1.0) * spacing)
let orig = -volume / 2.0
@@ -177,7 +176,7 @@ class BackgroundViewController: UIViewController {
internal func _setupAnimation()
{
let rotAxis = SCNVector3Make(0.25, 1.75, 1.0)
let rotAngle = CGFloat(Float(2.0) * π)
let rotAngle = 2.0 * π
let rotAction = SCNAction.repeatActionForever(SCNAction.rotateByAngle(rotAngle, aroundAxis: rotAxis, duration: 40.0))
_cubletsNode.runAction(rotAction)
}
+47
View File
@@ -0,0 +1,47 @@
//
// KSIRingView.h
// Kisai
//
// Created by Charles Magahern on 2/28/15.
// Copyright (c) 2015 zanneth. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface KSIRingPattern : NSObject <NSCopying, NSMutableCopying>
@property (nonatomic, readonly) UIColor *color;
@property (nonatomic, readonly) CGFloat beginSegmentAngle;
@property (nonatomic, readonly) CGFloat segmentWidth;
@property (nonatomic, readonly) CGFloat segmentLengthRadians;
@property (nonatomic, readonly) CGFloat segmentIntervalRadians;
@property (nonatomic, readonly) NSUInteger segmentsCount;
- (instancetype)initWithColor:(UIColor *)color
segmentLength:(CGFloat)segmentLengthInRadians
segmentsCount:(NSUInteger)segmentsCount;
@end
@interface KSIMutableRingPattern : KSIRingPattern
@property (nonatomic, strong) UIColor *color;
@property (nonatomic, assign) CGFloat beginSegmentAngle;
@property (nonatomic, assign) CGFloat segmentWidth;
@property (nonatomic, assign) CGFloat segmentLengthRadians;
@property (nonatomic, assign) CGFloat segmentIntervalRadians;
@property (nonatomic, assign) NSUInteger segmentsCount;
@end
// -----------------------------------------------------------------------------
@interface KSIRingView : UIView
@property (nonatomic, readonly) NSArray *ringPatterns; // KSIRingPattern(s)
- (void)addRingPattern:(KSIRingPattern *)pattern;
- (void)insertRingPattern:(KSIRingPattern *)pattern atIndex:(NSUInteger)index;
- (void)removeAllRingPatterns;
@end
+169
View File
@@ -0,0 +1,169 @@
//
// KSIRingView.m
// Kisai
//
// Created by Charles Magahern on 2/28/15.
// Copyright (c) 2015 zanneth. All rights reserved.
//
#import "KSIRingView.h"
@implementation KSIRingPattern {
@protected
UIColor *_color;
CGFloat _beginSegmentAngle;
CGFloat _segmentWidth;
CGFloat _segmentLengthRadians;
CGFloat _segmentIntervalRadians;
NSUInteger _segmentsCount;
}
- (instancetype)initWithColor:(UIColor *)color
segmentLength:(CGFloat)segmentLengthInRadians
segmentsCount:(NSUInteger)segmentsCount
{
self = [super init];
if (self) {
_color = color;
_beginSegmentAngle = 0.0;
_segmentWidth = 5.0;
_segmentLengthRadians = segmentLengthInRadians;
_segmentIntervalRadians = 0.0;
_segmentsCount = segmentsCount;
}
return self;
}
- (instancetype)init
{
return [self initWithColor:[UIColor whiteColor] segmentLength:(2.0 * M_PI) segmentsCount:1];
}
- (id)copyWithZone:(NSZone *)zone
{
return [self _copyWithZone:zone usingConcreteClass:[KSIRingPattern class]];
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return [self _copyWithZone:zone usingConcreteClass:[KSIMutableRingPattern class]];
}
#pragma mark - Internal
- (id)_copyWithZone:(NSZone *)zone usingConcreteClass:(Class)concreteClass
{
KSIRingPattern *copy = [[concreteClass allocWithZone:zone] init];
copy->_color = _color;
copy->_beginSegmentAngle = _beginSegmentAngle;
copy->_segmentWidth = _segmentWidth;
copy->_segmentLengthRadians = _segmentLengthRadians;
copy->_segmentIntervalRadians = _segmentIntervalRadians;
copy->_segmentsCount = _segmentsCount;
return copy;
}
@end
// -----------------------------------------------------------------------------
@implementation KSIMutableRingPattern
@dynamic color;
@dynamic beginSegmentAngle;
@dynamic segmentWidth;
@dynamic segmentLengthRadians;
@dynamic segmentIntervalRadians;
@dynamic segmentsCount;
- (void)setColor:(UIColor *)color { _color = color; }
- (void)setBeginSegmentAngle:(CGFloat)beginSegmentAngle { _beginSegmentAngle = beginSegmentAngle; }
- (void)setSegmentWidth:(CGFloat)segmentWidth { _segmentWidth = segmentWidth; }
- (void)setSegmentLengthRadians:(CGFloat)segmentLengthRadians { _segmentLengthRadians = segmentLengthRadians; }
- (void)setSegmentIntervalRadians:(CGFloat)segmentIntervalRadians { _segmentIntervalRadians = segmentIntervalRadians; }
- (void)setSegmentsCount:(NSUInteger)segmentsCount { _segmentsCount = segmentsCount; }
@end
// -----------------------------------------------------------------------------
@implementation KSIRingView {
NSMutableArray *_ringPatterns;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_ringPatterns = [[NSMutableArray alloc] init];
}
return self;
}
#pragma mark - Accessors
- (NSArray *)ringPatterns
{
return _ringPatterns;
}
#pragma mark - API
- (void)addRingPattern:(KSIRingPattern *)pattern
{
[_ringPatterns addObject:[pattern copy]];
[self setNeedsDisplay];
}
- (void)insertRingPattern:(KSIRingPattern *)pattern atIndex:(NSUInteger)index
{
[_ringPatterns insertObject:[pattern copy] atIndex:index];
[self setNeedsDisplay];
}
- (void)removeAllRingPatterns
{
[_ringPatterns removeAllObjects];
[self setNeedsDisplay];
}
#pragma mark - Drawing
- (void)drawRect:(CGRect)rect
{
const CGFloat radius = rint(rect.size.height / 2.0 - 1.0);
const CGPoint center = {
.x = rint(rect.size.width / 2.0),
.y = rint(rect.size.height / 2.0)
};
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGFloat currentRadius = radius;
for (KSIRingPattern *ringPattern in _ringPatterns) {
if (![ringPattern.color isEqual:[UIColor clearColor]]) {
NSUInteger segmentsCount = ringPattern.segmentsCount;
CGFloat currentAngle = ringPattern.beginSegmentAngle;
CGFloat segmentWidth = ringPattern.segmentWidth;
[ringPattern.color setStroke];
for (unsigned i = 0; i < segmentsCount; ++i) {
CGFloat beginAngle = currentAngle;
CGFloat endAngle = beginAngle + ringPattern.segmentLengthRadians;
CGContextAddArc(ctx, center.x, center.y, currentRadius - (segmentWidth / 2.0), beginAngle, endAngle, NO);
if (i < segmentsCount - 1) {
currentAngle += ringPattern.segmentIntervalRadians;
}
CGContextSetLineWidth(ctx, segmentWidth);
CGContextStrokePath(ctx);
}
}
currentRadius -= ringPattern.segmentWidth - 1.0;
}
}
@end
Binary file not shown.
@@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "XIONLogo.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "XIONLogoInnerRing.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "XIONLogoOuterRing.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "XIONLogoWithRing.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+6 -1
View File
@@ -22,6 +22,10 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIAppFonts</key>
<array>
<string>Orbitron-Medium.ttf</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
@@ -34,7 +38,8 @@
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
@@ -3,3 +3,4 @@
//
#import "NSValue+XIONAdditions.h"
#import "KSIRingView.h"
+90
View File
@@ -0,0 +1,90 @@
//
// HeaderView.swift
// XIONControlPanel
//
// Created by Charles Magahern on 12/30/15.
// Copyright © 2015 XION. All rights reserved.
//
import Darwin
import Foundation
import UIKit
class HeaderView: UIView {
private var _xionLogoView: XIONLogoView = XIONLogoView()
private var _xionTitleLabel: UILabel = UILabel()
private var _xionJapaneseLabel: UILabel = UILabel()
override init(frame: CGRect)
{
super.init(frame: frame)
self.backgroundColor = UIColor.blackColor()
self.addSubview(_xionLogoView)
_xionTitleLabel.font = UIFont(name: "Orbitron-Medium", size: 16.0)
_xionTitleLabel.text = "XION arcade system control panel"
_xionTitleLabel.textColor = UIColor.whiteColor()
self.addSubview(_xionTitleLabel)
_xionJapaneseLabel.font = UIFont(name: "Orbitron-Medium", size: 12.0)
_xionJapaneseLabel.text = "ザイーオンゲームセンターのシステム制御プログラム"
_xionJapaneseLabel.textColor = UIColor.whiteColor()
self.addSubview(_xionJapaneseLabel)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("unsupported")
}
override func layoutSubviews()
{
super.layoutSubviews()
let bounds = self.bounds
let hpadding = CGFloat(10.0)
let logoDimensions = rint(bounds.size.height / 1.2)
let logoFrame = CGRect(
x: hpadding,
y: rint(bounds.size.height / 2.0 - logoDimensions / 2.0),
width: logoDimensions,
height: logoDimensions
)
_xionLogoView.frame = logoFrame
let titleJPVerticalMargin: CGFloat = 5.0
let titleLabelSize = _xionTitleLabel.sizeThatFits(bounds.size)
let jpLabelSize = _xionJapaneseLabel.sizeThatFits(bounds.size)
let totalLabelsHeight = titleLabelSize.height + titleJPVerticalMargin + jpLabelSize.height
let titleFrame = CGRect(
x: CGRectGetMaxX(logoFrame) + hpadding * 2.0,
y: rint(bounds.size.height / 2.0 - totalLabelsHeight / 2.0),
width: titleLabelSize.width,
height: titleLabelSize.height
)
_xionTitleLabel.frame = titleFrame
let jpTitleFrame = CGRect(
x: titleFrame.origin.x,
y: CGRectGetMaxY(titleFrame) + titleJPVerticalMargin,
width: jpLabelSize.width,
height: jpLabelSize.height + 2.0
)
_xionJapaneseLabel.frame = jpTitleFrame
}
// MARK: API
func beginAnimating()
{
_xionLogoView.beginAnimating()
}
func stopAnimating()
{
_xionLogoView.stopAnimating()
}
}
+78
View File
@@ -0,0 +1,78 @@
//
// XIONLogoView.swift
// XIONControlPanel
//
// Created by Charles Magahern on 12/30/15.
// Copyright © 2015 XION. All rights reserved.
//
import UIKit
class XIONLogoView: UIView {
private var _xionLogoImageView: UIImageView = UIImageView()
private var _logoInnerRingImageView: UIImageView = UIImageView()
private var _logoOuterRingImageView: UIImageView = UIImageView()
override init(frame: CGRect)
{
super.init(frame: frame)
self.backgroundColor = UIColor.blackColor()
_xionLogoImageView.image = UIImage(named: "XIONLogoWithRing")
_xionLogoImageView.contentMode = .ScaleAspectFit
_logoInnerRingImageView.image = UIImage(named: "XIONLogoInnerRing")
_logoInnerRingImageView.contentMode = .ScaleAspectFit
_logoOuterRingImageView.image = UIImage(named: "XIONLogoOuterRing")
_logoOuterRingImageView.contentMode = .ScaleAspectFit
self.addSubview(_logoOuterRingImageView)
self.addSubview(_logoInnerRingImageView)
self.addSubview(_xionLogoImageView)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("unsupported")
}
override func layoutSubviews()
{
super.layoutSubviews()
let bounds = self.bounds
_xionLogoImageView.frame = bounds
_logoInnerRingImageView.frame = bounds
_logoOuterRingImageView.frame = bounds
}
// MARK: API
func beginAnimating()
{
let duration: NSTimeInterval = 20.0
let clockwiseAnim = CABasicAnimation(keyPath: "transform.rotation")
clockwiseAnim.fromValue = 0.0
clockwiseAnim.toValue = 2.0 * π
clockwiseAnim.duration = duration
clockwiseAnim.repeatCount = Float.infinity
let counterClockwiseAnim = CABasicAnimation(keyPath: "transform.rotation")
counterClockwiseAnim.fromValue = 2.0 * π
counterClockwiseAnim.toValue = 0.0
counterClockwiseAnim.duration = duration
counterClockwiseAnim.repeatCount = Float.infinity
_logoInnerRingImageView.layer.addAnimation(clockwiseAnim, forKey: "")
_logoOuterRingImageView.layer.addAnimation(counterClockwiseAnim, forKey: "")
}
func stopAnimating()
{
_logoInnerRingImageView.layer.removeAllAnimations()
_logoOuterRingImageView.layer.removeAllAnimations()
}
}