Add Waver

This commit is contained in:
kevinzhow
2015-04-01 13:57:17 +08:00
parent ddefdd4547
commit acf352bad0
3 changed files with 153 additions and 1 deletions
+4
View File
@@ -11,6 +11,7 @@
0A271FD71ACA055400822DFC /* YepAudioService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A271FD61ACA055400822DFC /* YepAudioService.swift */; };
0A5D83941AC5D3C8000045BF /* YepTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D83931AC5D3C8000045BF /* YepTabBarController.swift */; };
0A5D83991AC5D91E000045BF /* ContactsSearchTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D83981AC5D91E000045BF /* ContactsSearchTableViewController.swift */; };
0A6F46FD1ACBBF2D000CCD6F /* Waver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6F46FC1ACBBF2D000CCD6F /* Waver.swift */; };
0A8F54B11AB67D11004AD60E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8F54B01AB67D11004AD60E /* AppDelegate.swift */; };
0A8F54B61AB67D11004AD60E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0A8F54B41AB67D11004AD60E /* Main.storyboard */; };
0A8F54B81AB67D11004AD60E /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0A8F54B71AB67D11004AD60E /* Images.xcassets */; };
@@ -100,6 +101,7 @@
0A271FD61ACA055400822DFC /* YepAudioService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepAudioService.swift; path = Services/YepAudioService.swift; sourceTree = "<group>"; };
0A5D83931AC5D3C8000045BF /* YepTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepTabBarController.swift; path = ViewControllers/TabBar/YepTabBarController.swift; sourceTree = "<group>"; };
0A5D83981AC5D91E000045BF /* ContactsSearchTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContactsSearchTableViewController.swift; path = ViewControllers/Contacts/Search/ContactsSearchTableViewController.swift; sourceTree = "<group>"; };
0A6F46FC1ACBBF2D000CCD6F /* Waver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Waver.swift; sourceTree = "<group>"; };
0A8F54AB1AB67D11004AD60E /* Yep.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Yep.app; sourceTree = BUILT_PRODUCTS_DIR; };
0A8F54AF1AB67D11004AD60E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0A8F54B01AB67D11004AD60E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -486,6 +488,7 @@
502AE53B1AB871C5005BD199 /* Helpers */ = {
isa = PBXGroup;
children = (
0A6F46FC1ACBBF2D000CCD6F /* Waver.swift */,
502AE5391AB871C1005BD199 /* YepAlert.swift */,
502AE53C1AB87C0D005BD199 /* YepUserDefaults.swift */,
);
@@ -863,6 +866,7 @@
503315A01AC126100008A209 /* MessageToolbar.swift in Sources */,
502AE5531AB93215005BD199 /* ProfileFooterCell.swift in Sources */,
0A5D83991AC5D91E000045BF /* ContactsSearchTableViewController.swift in Sources */,
0A6F46FD1ACBBF2D000CCD6F /* Waver.swift in Sources */,
0A944C251AC8BB2F00037A06 /* YepStorageService.swift in Sources */,
5023DE521AB6C51300B3EE96 /* CGRect+Yep.swift in Sources */,
);
@@ -28,7 +28,7 @@ class ConversationViewController: UIViewController {
var conversationCollectionViewContentOffsetBeforeKeyboardWillHide = CGPointZero
var isKeyboardVisible = false
var keyboardHeight: CGFloat = 0
var keyboardShowTimes = 0 {
willSet {
println("set keyboardShowTimes \(newValue)")
+148
View File
@@ -0,0 +1,148 @@
//
// Waver.swift
// Waver-Swift
//
// Created by kevinzhow on 15/4/1.
// Copyright (c) 2015 kevinzhow. All rights reserved.
//
import UIKit
class Waver: UIView {
var numberOfWaves: Int = 5
var waveColor: UIColor = UIColor(red: 50/255.0, green: 167/255.0, blue: 255/255.0, alpha: 1.0)
private var phase: CGFloat = 0
var level: CGFloat! {
didSet {
self.phase+=self.phaseShift; // Move the wave
self.amplitude = fmax( level, self.idleAmplitude)
self.updateMeters()
}
}
var mainWaveWidth: CGFloat = 2.0
var decorativeWavesWidth: CGFloat = 1.0
var idleAmplitude: CGFloat = 0.01
var frequency: CGFloat = 1.2
internal private(set) var amplitude: CGFloat = 1.0
var density: CGFloat = 1.0
var phaseShift: CGFloat = -0.25
internal private(set) var waves: NSMutableArray = []
//
private var waveHeight: CGFloat!
private var waveWidth: CGFloat!
private var waveMid: CGFloat!
private var maxAmplitude: CGFloat!
var waverCallback: (() -> ())? {
didSet {
let displayLink = CADisplayLink(target: self, selector: Selector("callbackWaver"))
displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
for var i = 0; i < self.numberOfWaves; ++i {
var waveline = CAShapeLayer()
waveline.lineCap = kCALineCapButt
waveline.lineJoin = kCALineJoinRound
waveline.strokeColor = UIColor.clearColor().CGColor
waveline.fillColor = UIColor.clearColor().CGColor
waveline.lineWidth = (i==0 ? self.mainWaveWidth : self.decorativeWavesWidth)
var floatI = CGFloat(i)
var progressIndex = floatI/CGFloat(self.numberOfWaves)
var progress = 1.0 - progressIndex
var multiplier = min(1.0, (progress/3.0*2.0) + (1.0/3.0))
waveline.strokeColor = waveColor.colorWithAlphaComponent(( i == 0 ? 1.0 : 1.0*multiplier*0.4)).CGColor
self.layer.addSublayer(waveline)
self.waves.addObject(waveline)
}
}
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
private func setup() {
self.waveHeight = CGRectGetHeight(self.bounds) * 0.9
self.waveWidth = CGRectGetWidth(self.bounds)
self.waveMid = self.waveWidth/2.0
self.maxAmplitude = self.waveHeight - 4.0
}
func callbackWaver() {
waverCallback!()
}
private func updateMeters() {
UIGraphicsBeginImageContext(self.frame.size)
for var i=0; i < self.numberOfWaves; ++i {
var wavelinePath = UIBezierPath()
// Progress is a value between 1.0 and -0.5, determined by the current wave idx, which is used to alter the wave's amplitude.
var progress = 1.0 - CGFloat(i)/CGFloat(self.numberOfWaves)
var normedAmplitude = (1.5*progress-0.5)*self.amplitude
for var x = 0 as CGFloat; x<self.waveWidth + self.density; x += self.density {
//Thanks to https://github.com/stefanceriu/SCSiriWaveformView
// We use a parable to scale the sinus wave, that has its peak in the middle of the view.
var scaling = -pow(x/self.waveMid-1, 2) + 1 // make center bigger
var y = scaling*self.maxAmplitude*normedAmplitude
var temp = 2.0*CGFloat(M_PI)*(x/self.waveWidth)*self.frequency
var temp2 = temp+self.phase
y = CGFloat(y)*CGFloat(sinf(Float(temp2))) + self.waveHeight
if (x==0) {
wavelinePath.moveToPoint(CGPointMake(x, y))
}
else {
wavelinePath.addLineToPoint(CGPointMake(x, y))
}
}
var waveline = self.waves.objectAtIndex(i) as! CAShapeLayer
waveline.path = wavelinePath.CGPath
}
UIGraphicsEndImageContext()
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/
}