mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-10 21:36:49 +10:00
add SampleView to audio cells show sample wave
This commit is contained in:
@@ -72,6 +72,7 @@
|
||||
5033159D1AC101C80008A209 /* ChatRightTextCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5033159B1AC101C80008A209 /* ChatRightTextCell.xib */; };
|
||||
503315A01AC126100008A209 /* MessageToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5033159F1AC126100008A209 /* MessageToolbar.swift */; };
|
||||
503CAB431AC00CB100DFE830 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503CAB421AC00CB100DFE830 /* ConversationViewController.swift */; };
|
||||
504F41251ACE2D1D00FBB19A /* SampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504F41241ACE2D1D00FBB19A /* SampleView.swift */; };
|
||||
506EC20A1AC95BFC00CE42B3 /* UIFont+Yep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506EC2091AC95BFC00CE42B3 /* UIFont+Yep.swift */; };
|
||||
5076C56A1AC46B9F00B22952 /* FayeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5076C5691AC46B9F00B22952 /* FayeService.swift */; };
|
||||
508D17401ACCD2740092D666 /* YepButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508D173F1ACCD2740092D666 /* YepButton.swift */; };
|
||||
@@ -185,6 +186,7 @@
|
||||
5033159B1AC101C80008A209 /* ChatRightTextCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = ChatRightTextCell.xib; path = Views/Cells/ChatRightText/ChatRightTextCell.xib; sourceTree = "<group>"; };
|
||||
5033159F1AC126100008A209 /* MessageToolbar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MessageToolbar.swift; path = Views/MessageToolbar/MessageToolbar.swift; sourceTree = "<group>"; };
|
||||
503CAB421AC00CB100DFE830 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConversationViewController.swift; path = ViewControllers/Conversation/ConversationViewController.swift; sourceTree = "<group>"; };
|
||||
504F41241ACE2D1D00FBB19A /* SampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SampleView.swift; path = Views/AudioWaves/SampleView.swift; sourceTree = "<group>"; };
|
||||
506EC2091AC95BFC00CE42B3 /* UIFont+Yep.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIFont+Yep.swift"; path = "Extensions/UIFont+Yep.swift"; sourceTree = "<group>"; };
|
||||
5076C5691AC46B9F00B22952 /* FayeService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FayeService.swift; path = Services/FayeService.swift; sourceTree = "<group>"; };
|
||||
508D173F1ACCD2740092D666 /* YepButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepButton.swift; path = Views/Buttons/YepButton.swift; sourceTree = "<group>"; };
|
||||
@@ -659,6 +661,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
50A9D4521ACD393A000B2599 /* SquareWaveView.swift */,
|
||||
504F41241ACE2D1D00FBB19A /* SampleView.swift */,
|
||||
50A9D4531ACD393A000B2599 /* Waver.swift */,
|
||||
50A9D4541ACD393A000B2599 /* YepWaverView.swift */,
|
||||
);
|
||||
@@ -958,6 +961,7 @@
|
||||
502AE5271AB72D06005BD199 /* YepNetworking.swift in Sources */,
|
||||
5076C56A1AC46B9F00B22952 /* FayeService.swift in Sources */,
|
||||
5099B9C71AB99F7B002F940B /* RegisterPickAvatarViewController.swift in Sources */,
|
||||
504F41251ACE2D1D00FBB19A /* SampleView.swift in Sources */,
|
||||
502AE5291AB81076005BD199 /* YepService.swift in Sources */,
|
||||
502AE51E1AB712D2005BD199 /* RegisterPickNameViewController.swift in Sources */,
|
||||
50E114F91ABC137A00F13000 /* YepServiceSync.swift in Sources */,
|
||||
|
||||
@@ -33,4 +33,12 @@ class YepConfig {
|
||||
class func messageImageViewAspectRatio() -> CGFloat {
|
||||
return 4.0 / 3.0
|
||||
}
|
||||
|
||||
class func audioSampleWidth() -> CGFloat {
|
||||
return 2
|
||||
}
|
||||
|
||||
class func audioSampleGap() -> CGFloat {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,9 @@ class YepAudioService: NSObject {
|
||||
if self.audioPlayer.play() {
|
||||
println("Do Play audio \(error)")
|
||||
}
|
||||
|
||||
} else {
|
||||
println("play audio \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,6 +588,27 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
cell.avatarImageView.image = roundImage
|
||||
}
|
||||
}
|
||||
|
||||
if !message.metaData.isEmpty {
|
||||
|
||||
if let data = message.metaData.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
|
||||
if let metaDataDict = decodeJSON(data) {
|
||||
|
||||
if let audioSamples = metaDataDict["audio_samples"] as? [CGFloat] {
|
||||
cell.sampleViewWidthConstraint.constant = CGFloat(audioSamples.count) * (YepConfig.audioSampleWidth() + YepConfig.audioSampleGap()) - YepConfig.audioSampleGap() // 最后最后一个 gap 不要
|
||||
cell.sampleView.samples = audioSamples
|
||||
|
||||
if let audioDuration = metaDataDict["audio_duration"] as? Double {
|
||||
cell.audioDurationLabel.text = NSString(format: "%.1f\"", audioDuration) as String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
cell.sampleViewWidthConstraint.constant = 15 * (YepConfig.audioSampleWidth() + YepConfig.audioSampleGap())
|
||||
cell.audioDurationLabel.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
return cell
|
||||
|
||||
@@ -644,6 +665,27 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
}
|
||||
}
|
||||
|
||||
if !message.metaData.isEmpty {
|
||||
|
||||
if let data = message.metaData.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) {
|
||||
if let metaDataDict = decodeJSON(data) {
|
||||
|
||||
if let audioSamples = metaDataDict["audio_samples"] as? [CGFloat] {
|
||||
cell.sampleViewWidthConstraint.constant = CGFloat(audioSamples.count) * (YepConfig.audioSampleWidth() + YepConfig.audioSampleGap()) - YepConfig.audioSampleGap() // 最后一个 gap 不要
|
||||
cell.sampleView.samples = audioSamples
|
||||
|
||||
if let audioDuration = metaDataDict["audio_duration"] as? Double {
|
||||
cell.audioDurationLabel.text = NSString(format: "%.1f\"", audioDuration) as String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
cell.sampleViewWidthConstraint.constant = 15 * (YepConfig.audioSampleWidth() + YepConfig.audioSampleGap())
|
||||
cell.audioDurationLabel.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
return cell
|
||||
|
||||
default:
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// SampleView.swift
|
||||
// Yep
|
||||
//
|
||||
// Created by NIX on 15/4/3.
|
||||
// Copyright (c) 2015年 Catch Inc. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@IBDesignable
|
||||
class SampleView: UIView {
|
||||
|
||||
var samples: [CGFloat]? {
|
||||
didSet {
|
||||
setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
@IBInspectable var sampleColor: UIColor = UIColor.yepTintColor() {
|
||||
willSet {
|
||||
waveLayer.strokeColor = newValue.CGColor
|
||||
}
|
||||
}
|
||||
|
||||
let sampleWidth: CGFloat = YepConfig.audioSampleWidth()
|
||||
let sampleGap = YepConfig.audioSampleGap()
|
||||
|
||||
lazy var waveLayer: CAShapeLayer = {
|
||||
let layer = CAShapeLayer()
|
||||
layer.lineWidth = self.sampleWidth
|
||||
layer.strokeColor = self.sampleColor.CGColor
|
||||
return layer
|
||||
}()
|
||||
|
||||
override func didMoveToSuperview() {
|
||||
super.didMoveToSuperview()
|
||||
|
||||
backgroundColor = UIColor.clearColor()
|
||||
|
||||
layer.addSublayer(waveLayer)
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
let wavePath = UIBezierPath()
|
||||
|
||||
if let samples = samples {
|
||||
|
||||
if samples.count > 0 {
|
||||
|
||||
let viewHeight = self.bounds.height
|
||||
|
||||
for (index, percent) in enumerate(samples) {
|
||||
|
||||
let x = CGFloat(index) * sampleWidth + sampleGap * CGFloat(index)
|
||||
|
||||
let sampleHeight = percent * viewHeight
|
||||
|
||||
wavePath.moveToPoint(CGPointMake(x, viewHeight / 2.0 - sampleHeight / 2.0))
|
||||
wavePath.addLineToPoint(CGPointMake(x, sampleHeight / 2.0 + viewHeight / 2.0))
|
||||
}
|
||||
|
||||
waveLayer.path = wavePath.CGPath
|
||||
}
|
||||
|
||||
} else {
|
||||
samples = [0.05, 0.05, 0.1, 0.2, 0.3, 0.6, 0.2, 0.7, 0.9, 0.7, 0.6, 0.3, 0.1, 0.1, 0.05] // count = 15
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,10 +14,19 @@ class ChatLeftAudioCell: UICollectionViewCell {
|
||||
|
||||
@IBOutlet weak var bubbleImageView: UIImageView!
|
||||
|
||||
@IBOutlet weak var sampleView: SampleView!
|
||||
@IBOutlet weak var sampleViewWidthConstraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var audioDurationLabel: UILabel!
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
bubbleImageView.tintColor = UIColor.leftBubbleTintColor()
|
||||
|
||||
sampleView.sampleColor = UIColor.rightBubbleTintColor()
|
||||
|
||||
audioDurationLabel.textColor = UIColor.blackColor()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,13 +36,16 @@
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="mlz-An-Tuw" userLabel="Wave View">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="mlz-An-Tuw" userLabel="Wave View" customClass="SampleView" customModule="Yep" customModuleProvider="target">
|
||||
<rect key="frame" x="48" y="0.0" width="87" height="40"/>
|
||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="87" id="12R-C6-EyM"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2"" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Nar-PJ-uc5" userLabel="Time Length Label">
|
||||
<rect key="frame" x="48" y="0.0" width="87" height="40"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<rect key="frame" x="43" y="0.0" width="97" height="40"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
@@ -53,15 +56,14 @@
|
||||
<constraint firstAttribute="bottom" secondItem="j0p-8V-Tjb" secondAttribute="bottom" id="J5p-D5-MJf"/>
|
||||
<constraint firstAttribute="trailing" secondItem="mlz-An-Tuw" secondAttribute="trailing" constant="15" id="Lps-ic-PsY"/>
|
||||
<constraint firstAttribute="height" constant="40" id="N3O-u2-oYu"/>
|
||||
<constraint firstItem="Nar-PJ-uc5" firstAttribute="trailing" secondItem="mlz-An-Tuw" secondAttribute="trailing" id="PWf-JE-OeL"/>
|
||||
<constraint firstItem="Nar-PJ-uc5" firstAttribute="trailing" secondItem="mlz-An-Tuw" secondAttribute="trailing" constant="5" id="PWf-JE-OeL"/>
|
||||
<constraint firstItem="mlz-An-Tuw" firstAttribute="top" secondItem="Whb-i5-kn8" secondAttribute="top" id="RO3-HD-5VX"/>
|
||||
<constraint firstAttribute="centerY" secondItem="JJr-x8-Ljw" secondAttribute="centerY" id="RhN-1T-q4N"/>
|
||||
<constraint firstItem="j0p-8V-Tjb" firstAttribute="leading" secondItem="Whb-i5-kn8" secondAttribute="leading" id="TmR-CA-j6B"/>
|
||||
<constraint firstItem="mlz-An-Tuw" firstAttribute="leading" secondItem="JJr-x8-Ljw" secondAttribute="trailing" constant="5" id="UwV-wg-0GN"/>
|
||||
<constraint firstItem="Nar-PJ-uc5" firstAttribute="leading" secondItem="mlz-An-Tuw" secondAttribute="leading" id="YIF-on-6fg"/>
|
||||
<constraint firstItem="Nar-PJ-uc5" firstAttribute="leading" secondItem="mlz-An-Tuw" secondAttribute="leading" constant="-5" id="YIF-on-6fg"/>
|
||||
<constraint firstItem="Nar-PJ-uc5" firstAttribute="bottom" secondItem="mlz-An-Tuw" secondAttribute="bottom" id="qyd-GU-56h"/>
|
||||
<constraint firstAttribute="trailing" secondItem="j0p-8V-Tjb" secondAttribute="trailing" id="r6r-TN-l5p"/>
|
||||
<constraint firstAttribute="width" constant="150" id="sta-YS-9h3"/>
|
||||
<constraint firstItem="Nar-PJ-uc5" firstAttribute="top" secondItem="mlz-An-Tuw" secondAttribute="top" id="vdR-5f-8fd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="mlz-An-Tuw" secondAttribute="bottom" id="zwN-D3-Jl5"/>
|
||||
</constraints>
|
||||
@@ -77,8 +79,11 @@
|
||||
</constraints>
|
||||
<size key="customSize" width="276" height="126"/>
|
||||
<connections>
|
||||
<outlet property="audioDurationLabel" destination="Nar-PJ-uc5" id="cAT-ry-mhm"/>
|
||||
<outlet property="avatarImageView" destination="1K0-wd-BOr" id="ldH-Pm-vDG"/>
|
||||
<outlet property="bubbleImageView" destination="j0p-8V-Tjb" id="Uca-XB-lkc"/>
|
||||
<outlet property="sampleView" destination="mlz-An-Tuw" id="Vne-hR-WQH"/>
|
||||
<outlet property="sampleViewWidthConstraint" destination="12R-C6-EyM" id="UMe-Ql-Saj"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="360" y="358"/>
|
||||
</collectionViewCell>
|
||||
|
||||
@@ -13,11 +13,20 @@ class ChatRightAudioCell: UICollectionViewCell {
|
||||
@IBOutlet weak var avatarImageView: UIImageView!
|
||||
|
||||
@IBOutlet weak var bubbleImageView: UIImageView!
|
||||
|
||||
@IBOutlet weak var sampleView: SampleView!
|
||||
@IBOutlet weak var sampleViewWidthConstraint: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var audioDurationLabel: UILabel!
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
bubbleImageView.tintColor = UIColor.rightBubbleTintColor()
|
||||
|
||||
sampleView.sampleColor = UIColor.leftBubbleTintColor()
|
||||
|
||||
audioDurationLabel.textColor = UIColor.whiteColor()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,13 +37,16 @@
|
||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</state>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ynj-aF-z4D" userLabel="Wave View">
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ynj-aF-z4D" userLabel="Wave View" customClass="SampleView" customModule="Yep" customModuleProvider="target">
|
||||
<rect key="frame" x="41" y="0.0" width="89" height="40"/>
|
||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="89" id="LKH-Qz-uop"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2"" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="alU-Q7-YxY" userLabel="Time Length Label">
|
||||
<rect key="frame" x="41" y="0.0" width="89" height="40"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<rect key="frame" x="36" y="0.0" width="99" height="40"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
@@ -52,14 +55,13 @@
|
||||
<constraint firstItem="XTQ-XN-AqX" firstAttribute="leading" secondItem="knU-A0-FO4" secondAttribute="leading" constant="6" id="2gQ-ob-cgb"/>
|
||||
<constraint firstAttribute="trailing" secondItem="IUw-Mk-XlZ" secondAttribute="trailing" id="8dj-VI-b8r"/>
|
||||
<constraint firstAttribute="centerY" secondItem="XTQ-XN-AqX" secondAttribute="centerY" id="9sZ-NN-OjE"/>
|
||||
<constraint firstItem="alU-Q7-YxY" firstAttribute="leading" secondItem="ynj-aF-z4D" secondAttribute="leading" id="DWl-Kd-47z"/>
|
||||
<constraint firstItem="alU-Q7-YxY" firstAttribute="leading" secondItem="ynj-aF-z4D" secondAttribute="leading" constant="-5" id="DWl-Kd-47z"/>
|
||||
<constraint firstItem="alU-Q7-YxY" firstAttribute="bottom" secondItem="ynj-aF-z4D" secondAttribute="bottom" id="FfY-Nf-2Wq"/>
|
||||
<constraint firstAttribute="trailing" secondItem="ynj-aF-z4D" secondAttribute="trailing" constant="20" id="HSM-71-9gP"/>
|
||||
<constraint firstAttribute="width" constant="150" id="LBt-mx-R7u"/>
|
||||
<constraint firstItem="IUw-Mk-XlZ" firstAttribute="leading" secondItem="knU-A0-FO4" secondAttribute="leading" id="LgR-iA-qgz"/>
|
||||
<constraint firstItem="IUw-Mk-XlZ" firstAttribute="top" secondItem="knU-A0-FO4" secondAttribute="top" id="PED-I8-vTn"/>
|
||||
<constraint firstItem="ynj-aF-z4D" firstAttribute="top" secondItem="knU-A0-FO4" secondAttribute="top" id="RIA-cc-ovU"/>
|
||||
<constraint firstItem="alU-Q7-YxY" firstAttribute="trailing" secondItem="ynj-aF-z4D" secondAttribute="trailing" id="bWp-na-rZM"/>
|
||||
<constraint firstItem="alU-Q7-YxY" firstAttribute="trailing" secondItem="ynj-aF-z4D" secondAttribute="trailing" constant="5" id="bWp-na-rZM"/>
|
||||
<constraint firstAttribute="bottom" secondItem="IUw-Mk-XlZ" secondAttribute="bottom" id="fGm-iu-3L1"/>
|
||||
<constraint firstItem="alU-Q7-YxY" firstAttribute="top" secondItem="ynj-aF-z4D" secondAttribute="top" id="fyp-2L-t3i"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ynj-aF-z4D" secondAttribute="bottom" id="mJb-Pl-UbX"/>
|
||||
@@ -78,8 +80,11 @@
|
||||
</constraints>
|
||||
<size key="customSize" width="316" height="105"/>
|
||||
<connections>
|
||||
<outlet property="audioDurationLabel" destination="alU-Q7-YxY" id="2dD-Pg-BJw"/>
|
||||
<outlet property="avatarImageView" destination="76j-Ht-EsY" id="uPV-sw-dlg"/>
|
||||
<outlet property="bubbleImageView" destination="IUw-Mk-XlZ" id="eH5-bH-lrf"/>
|
||||
<outlet property="sampleView" destination="ynj-aF-z4D" id="FIe-OE-IN2"/>
|
||||
<outlet property="sampleViewWidthConstraint" destination="LKH-Qz-uop" id="TsO-kt-Lg5"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="434" y="419.5"/>
|
||||
</collectionViewCell>
|
||||
|
||||
Reference in New Issue
Block a user