Răsfoiți Sursa

Merge branch 'fix/ios_im_audio_button' into 'develop'

ios聊天语音消息发送上滑取消功能优化

See merge request o2oa/o2oa!1061
楼国栋 5 ani în urmă
părinte
comite
4453223e42

+ 4 - 0
o2ios/O2Platform.xcodeproj/project.pbxproj

@@ -247,6 +247,7 @@
 		B1D1BC8B234C5C49002025DA /* CloudFileShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D1BC8A234C5C49002025DA /* CloudFileShareViewController.swift */; };
 		B1D1BC8B234C5C49002025DA /* CloudFileShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D1BC8A234C5C49002025DA /* CloudFileShareViewController.swift */; };
 		B1D1BC8D234C7EC9002025DA /* CloudFileFolderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D1BC8C234C7EC9002025DA /* CloudFileFolderCell.swift */; };
 		B1D1BC8D234C7EC9002025DA /* CloudFileFolderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D1BC8C234C7EC9002025DA /* CloudFileFolderCell.swift */; };
 		B1D1BC8F234C8349002025DA /* CloudFileCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D1BC8E234C8349002025DA /* CloudFileCell.swift */; };
 		B1D1BC8F234C8349002025DA /* CloudFileCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D1BC8E234C8349002025DA /* CloudFileCell.swift */; };
+		B1D4AFED24B409A9004E648E /* AudioTouchButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D4AFEC24B409A9004E648E /* AudioTouchButton.swift */; };
 		B1DA305F2282754500669418 /* QCalendarPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DA305E2282754500669418 /* QCalendarPicker.swift */; };
 		B1DA305F2282754500669418 /* QCalendarPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DA305E2282754500669418 /* QCalendarPicker.swift */; };
 		B1DB6EA5237E6F2C00D7BA94 /* O2VersionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DB6EA4237E6F2C00D7BA94 /* O2VersionInfoModel.swift */; };
 		B1DB6EA5237E6F2C00D7BA94 /* O2VersionInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DB6EA4237E6F2C00D7BA94 /* O2VersionInfoModel.swift */; };
 		B1DE853823602D36003C36E2 /* Languager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DE853723602D36003C36E2 /* Languager.swift */; };
 		B1DE853823602D36003C36E2 /* Languager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1DE853723602D36003C36E2 /* Languager.swift */; };
@@ -1583,6 +1584,7 @@
 		B1D1BC8A234C5C49002025DA /* CloudFileShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileShareViewController.swift; sourceTree = "<group>"; };
 		B1D1BC8A234C5C49002025DA /* CloudFileShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileShareViewController.swift; sourceTree = "<group>"; };
 		B1D1BC8C234C7EC9002025DA /* CloudFileFolderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileFolderCell.swift; sourceTree = "<group>"; };
 		B1D1BC8C234C7EC9002025DA /* CloudFileFolderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileFolderCell.swift; sourceTree = "<group>"; };
 		B1D1BC8E234C8349002025DA /* CloudFileCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileCell.swift; sourceTree = "<group>"; };
 		B1D1BC8E234C8349002025DA /* CloudFileCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloudFileCell.swift; sourceTree = "<group>"; };
+		B1D4AFEC24B409A9004E648E /* AudioTouchButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioTouchButton.swift; sourceTree = "<group>"; };
 		B1DA305E2282754500669418 /* QCalendarPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QCalendarPicker.swift; sourceTree = "<group>"; };
 		B1DA305E2282754500669418 /* QCalendarPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QCalendarPicker.swift; sourceTree = "<group>"; };
 		B1DB6EA4237E6F2C00D7BA94 /* O2VersionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = O2VersionInfoModel.swift; sourceTree = "<group>"; };
 		B1DB6EA4237E6F2C00D7BA94 /* O2VersionInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = O2VersionInfoModel.swift; sourceTree = "<group>"; };
 		B1DE853723602D36003C36E2 /* Languager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Languager.swift; sourceTree = "<group>"; };
 		B1DE853723602D36003C36E2 /* Languager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Languager.swift; sourceTree = "<group>"; };
@@ -2660,6 +2662,7 @@
 				B15BE10D249A107C008CD1DB /* IMAudioView.swift */,
 				B15BE10D249A107C008CD1DB /* IMAudioView.swift */,
 				B183987C249AFF64001C6FAA /* IMLocationView.xib */,
 				B183987C249AFF64001C6FAA /* IMLocationView.xib */,
 				B18398AC249B00AA001C6FAA /* IMLocationView.swift */,
 				B18398AC249B00AA001C6FAA /* IMLocationView.swift */,
+				B1D4AFEC24B409A9004E648E /* AudioTouchButton.swift */,
 			);
 			);
 			path = View;
 			path = View;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -6131,6 +6134,7 @@
 				E4B7816F1DF8F359007B58A9 /* CMSCategoryItemCell.swift in Sources */,
 				E4B7816F1DF8F359007B58A9 /* CMSCategoryItemCell.swift in Sources */,
 				E41512631ED80AF3006531B0 /* ZoneNavigationBarManager.swift in Sources */,
 				E41512631ED80AF3006531B0 /* ZoneNavigationBarManager.swift in Sources */,
 				E4B888771D9D48F1002E1A46 /* Group.swift in Sources */,
 				E4B888771D9D48F1002E1A46 /* Group.swift in Sources */,
+				B1D4AFED24B409A9004E648E /* AudioTouchButton.swift in Sources */,
 				E4B888911D9D48F1002E1A46 /* UIViewExt.m in Sources */,
 				E4B888911D9D48F1002E1A46 /* UIViewExt.m in Sources */,
 				B1BA42B824133AC40081CED8 /* TaskCreateData.swift in Sources */,
 				B1BA42B824133AC40081CED8 /* TaskCreateData.swift in Sources */,
 				09E02E871F16319600579887 /* DiskCache.swift in Sources */,
 				09E02E871F16319600579887 /* DiskCache.swift in Sources */,

+ 56 - 0
o2ios/O2Platform/App/IM-聊天/IMChatViewController.swift

@@ -42,6 +42,12 @@ class IMChatViewController: UIViewController {
         view.delegate = self
         view.delegate = self
         return view
         return view
     }()
     }()
+    //录音的时候显示的view
+    private var voiceIconImage: UIImageView?
+    private var voiceIocnTitleLable: UILabel?
+    private var voiceImageSuperView: UIView?
+    
+    
     //预览文件
     //预览文件
     private lazy var previewVC: CloudFilePreviewController = {
     private lazy var previewVC: CloudFilePreviewController = {
         return CloudFilePreviewController()
         return CloudFilePreviewController()
@@ -473,6 +479,55 @@ class IMChatViewController: UIViewController {
 
 
 // MARK: - 录音delegate
 // MARK: - 录音delegate
 extension IMChatViewController: IMChatAudioViewDelegate {
 extension IMChatViewController: IMChatAudioViewDelegate {
+    
+    func showAudioRecordingView() {
+        if self.voiceIconImage == nil {
+            self.voiceImageSuperView = UIView()
+            self.view.addSubview(self.voiceImageSuperView!)
+            self.voiceImageSuperView?.backgroundColor = UIColor(displayP3Red: 0, green: 0, blue: 0, alpha: 0.6)
+             
+            self.voiceImageSuperView?.snp_makeConstraints { (make) in
+                make.center.equalTo(self.view)
+                make.size.equalTo(CGSize(width:140, height:140))
+            }
+        
+            self.voiceIconImage = UIImageView()
+            self.voiceImageSuperView?.addSubview(self.voiceIconImage!)
+            self.voiceIconImage?.snp_makeConstraints { (make) in
+                make.top.left.equalTo(self.voiceImageSuperView!).inset(UIEdgeInsets(top: 20, left: 35, bottom: 0, right: 0))
+                make.size.equalTo(CGSize(width: 70, height: 70))
+            }
+            let voiceIconTitleLabel = UILabel()
+            self.voiceIocnTitleLable = voiceIconTitleLabel
+            self.voiceIconImage?.addSubview(voiceIconTitleLabel)
+            voiceIconTitleLabel.textColor = UIColor.white
+            voiceIconTitleLabel.font = .systemFont(ofSize: 12)
+            voiceIconTitleLabel.text = "松开发送,上滑取消"
+            voiceIconTitleLabel.snp_makeConstraints { (make) in
+                make.bottom.equalTo(self.voiceImageSuperView!).offset(-15)
+                make.centerX.equalTo(self.voiceImageSuperView!)
+            }
+        }
+        self.voiceImageSuperView?.isHidden = false
+        self.voiceIconImage?.image = UIImage(named: "chat_audio_voice")
+        self.voiceIocnTitleLable?.text = "松开发送,上滑取消";
+       
+    }
+    
+    func hideAudioRecordingView() {
+        self.voiceImageSuperView?.isHidden = true
+    }
+    
+    func changeRecordingView2uplide() {
+        self.voiceIocnTitleLable?.text = "松开手指,取消发送";
+        self.voiceIconImage?.image = UIImage(named: "chat_audio_cancel")
+    }
+    
+    func changeRecordingView2down() {
+        self.voiceIconImage?.image = UIImage(named: "chat_audio_voice")
+        self.voiceIocnTitleLable?.text = "松开发送,上滑取消";
+    }
+    
     func sendVoice(path: String, voice: Data, duration: String) {
     func sendVoice(path: String, voice: Data, duration: String) {
         let msg = IMMessageBodyInfo()
         let msg = IMMessageBodyInfo()
         msg.fileTempPath = path
         msg.fileTempPath = path
@@ -484,6 +539,7 @@ extension IMChatViewController: IMChatAudioViewDelegate {
         DDLogDebug("音频文件:\(fileName)")
         DDLogDebug("音频文件:\(fileName)")
         self.uploadFileAndSendMsg(messageId: msgId, data: voice, fileName: fileName, type: o2_im_msg_type_audio)
         self.uploadFileAndSendMsg(messageId: msgId, data: voice, fileName: fileName, type: o2_im_msg_type_audio)
     }
     }
+    
 }
 }
 
 
 // MARK: - 拍照delegate
 // MARK: - 拍照delegate

+ 89 - 0
o2ios/O2Platform/App/IM-聊天/View/AudioTouchButton.swift

@@ -0,0 +1,89 @@
+//
+//  AudioTouchButton.swift
+//  O2Platform
+//
+//  Created by FancyLou on 2020/7/7.
+//  Copyright © 2020 zoneland. All rights reserved.
+//
+
+import UIKit
+
+class AudioTouchButton: UIView {
+
+    var areaY: CGFloat = 40
+    var clickTime = 0.5
+    var touchBegan: (()->Void)? = nil
+    var upglide: (()->Void)? = nil
+    var down: (()->Void)? = nil
+    var touchEnd: (()->Void)? = nil
+    var voiceButton: UIButton?
+    
+    private var isBegan: Bool = false
+    private var timer: Timer?
+
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        self.areaY = -40
+        self.clickTime = 0.5
+        self.isBegan = false
+        self.voiceButton = UIButton(type: .custom)
+        self.addSubview(self.voiceButton!)
+        self.voiceButton?.titleLabel?.font = .systemFont(ofSize: 14)
+        self.voiceButton?.isUserInteractionEnabled = false
+        self.voiceButton?.snp_makeConstraints({ (make) in
+            make.edges.equalTo(self)
+        })
+        
+        
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
+        if self.voiceButton?.isSelected == true {
+            return true
+        }else {
+            return super.point(inside: point, with: event)
+        }
+    }
+    
+    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
+        let timer = Timer.scheduledTimer(timeInterval: self.clickTime, target: self, selector: #selector(timeAction), userInfo: nil, repeats: false)
+        print("++++++++++++++++++开始")
+        self.timer = timer
+    }
+    
+    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
+        if self.voiceButton?.isSelected == true {
+            let anchTouch = touches.first
+            let point = anchTouch?.location(in: self)
+            if point?.y ?? 0 > self.areaY {
+                self.down?()
+            }else {
+                self.upglide?()
+            }
+        }
+        
+    }
+    
+    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
+        if self.voiceButton?.isSelected == true {
+            self.touchEnd?()
+        }
+        self.voiceButton?.isSelected = false
+        self.timer?.invalidate()
+        self.timer = nil
+        print("+++++++++++++++++取消")
+    }
+
+    @objc func timeAction() {
+        self.touchBegan?()
+        print("++++++++++++执行");
+        self.voiceButton?.isSelected = true
+        self.timer?.invalidate()
+    }
+    
+}

+ 47 - 10
o2ios/O2Platform/App/IM-聊天/View/IMChatAudioView.swift

@@ -12,11 +12,18 @@ import CocoaLumberjack
 
 
 protocol IMChatAudioViewDelegate {
 protocol IMChatAudioViewDelegate {
     func sendVoice(path: String, voice: Data, duration: String)
     func sendVoice(path: String, voice: Data, duration: String)
+    func showAudioRecordingView() //录音状态
+    func hideAudioRecordingView() //关闭录音状态
+    func changeRecordingView2uplide() //取消发送的状态
+    func changeRecordingView2down()// 可以发送的状态
 }
 }
 class IMChatAudioView: UIView {
 class IMChatAudioView: UIView {
     
     
     @IBOutlet weak var audioViewTitle: UILabel!
     @IBOutlet weak var audioViewTitle: UILabel!
     @IBOutlet weak var audioRecordBtn: UIButton!
     @IBOutlet weak var audioRecordBtn: UIButton!
+    @IBOutlet weak var audioBtnContainer: UIView!
+    
+    private var touchBtn: AudioTouchButton?
     
     
     private var isCancel = false
     private var isCancel = false
     
     
@@ -29,9 +36,36 @@ class IMChatAudioView: UIView {
     var delegate: IMChatAudioViewDelegate?
     var delegate: IMChatAudioViewDelegate?
     
     
     override func awakeFromNib() {
     override func awakeFromNib() {
-        audioRecordBtn.addTarget(self, action: #selector(startRecord), for: .touchDown)
-        audioRecordBtn.addTarget(self, action: #selector(cancelRecord), for: .touchDragExit)
-        audioRecordBtn.addTarget(self, action: #selector(finishRecord), for: .touchUpInside)
+//        audioRecordBtn.addTarget(self, action: #selector(startRecord), for: .touchDown)
+//        audioRecordBtn.addTarget(self, action: #selector(cancelRecord), for: .touchDragExit)
+//        audioRecordBtn.addTarget(self, action: #selector(finishRecord), for: .touchUpInside)
+        
+        let audioTouchBtn = AudioTouchButton(frame: CGRect(x: 0, y: 0, width: 98, height: 98))
+        self.audioBtnContainer.addSubview(audioTouchBtn)
+        self.touchBtn = audioTouchBtn
+        self.touchBtn?.touchBegan = {
+            DDLogDebug("touchBegan 点击............这里开始录音.......")
+            self.delegate?.showAudioRecordingView()
+            self.startRecord()
+        }
+        self.touchBtn?.upglide = {
+            self.isCancel = true
+            self.delegate?.changeRecordingView2uplide()
+        }
+        self.touchBtn?.down = {
+            self.isCancel = false
+            self.delegate?.changeRecordingView2down()
+        }
+        self.touchBtn?.touchEnd = {
+            DDLogDebug("touchEnd 点击.........这里结束录音..........")
+            self.delegate?.hideAudioRecordingView()
+            self.finishRecord()
+        }
+//        self.touchBtn?.voiceButton?.setTitle("按住说话", for: .normal)
+        self.touchBtn?.voiceButton?.setImage(UIImage(named: "chat_mic"), for: .normal)
+        self.touchBtn?.backgroundColor = UIColor(hex: "#F3F3F3")
+        self.touchBtn?.layer.cornerRadius = 49
+        self.touchBtn?.layer.masksToBounds = true
     }
     }
      
      
     
     
@@ -51,13 +85,13 @@ class IMChatAudioView: UIView {
         }
         }
     }
     }
     
     
-    @objc private func cancelRecord() {
-        DDLogError("cancelRecord record...................")
-        self.audioViewTitle.text = "按住说话"
-        self.isCancel = true
-        //取消录音
-        recordManager.cancelledDeleteWithCompletion()
-    }
+//    @objc private func cancelRecord() {
+//        DDLogError("cancelRecord record...................")
+//        self.audioViewTitle.text = "按住说话"
+//        self.isCancel = true
+//        //取消录音
+//        recordManager.cancelledDeleteWithCompletion()
+//    }
     @objc private func finishRecord() {
     @objc private func finishRecord() {
         DDLogError("finish record...................")
         DDLogError("finish record...................")
         self.audioViewTitle.text = "按住说话"
         self.audioViewTitle.text = "按住说话"
@@ -74,6 +108,9 @@ class IMChatAudioView: UIView {
             recordManager.convertCafToMp3(cafPath: recordManager.recordPath!, mp3Path: filePath)
             recordManager.convertCafToMp3(cafPath: recordManager.recordPath!, mp3Path: filePath)
             let data = try! Data(contentsOf: URL(fileURLWithPath: filePath))
             let data = try! Data(contentsOf: URL(fileURLWithPath: filePath))
             delegate?.sendVoice(path: filePath, voice: data, duration: recordManager.recordDuration!)
             delegate?.sendVoice(path: filePath, voice: data, duration: recordManager.recordDuration!)
+        }else {
+            //取消录音
+            recordManager.cancelledDeleteWithCompletion()
         }
         }
     }
     }
 }
 }

+ 12 - 1
o2ios/O2Platform/App/IM-聊天/View/IMChatAudioView.xib

@@ -14,7 +14,7 @@
             <rect key="frame" x="0.0" y="0.0" width="414" height="196"/>
             <rect key="frame" x="0.0" y="0.0" width="414" height="196"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <subviews>
             <subviews>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wVh-0l-AFu">
+                <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="wVh-0l-AFu">
                     <rect key="frame" x="158" y="49" width="98" height="98"/>
                     <rect key="frame" x="158" y="49" width="98" height="98"/>
                     <color key="backgroundColor" red="0.95294117649999999" green="0.95294117649999999" blue="0.95294117649999999" alpha="1" colorSpace="calibratedRGB"/>
                     <color key="backgroundColor" red="0.95294117649999999" green="0.95294117649999999" blue="0.95294117649999999" alpha="1" colorSpace="calibratedRGB"/>
                     <constraints>
                     <constraints>
@@ -34,17 +34,28 @@
                     <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <nil key="highlightedColor"/>
                     <nil key="highlightedColor"/>
                 </label>
                 </label>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="MOK-Ap-tLT">
+                    <rect key="frame" x="158" y="49" width="98" height="98"/>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="98" id="Gqq-bx-nM3"/>
+                        <constraint firstAttribute="height" constant="98" id="lyM-c3-YEW"/>
+                    </constraints>
+                </view>
             </subviews>
             </subviews>
             <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
             <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
             <constraints>
             <constraints>
                 <constraint firstItem="wVh-0l-AFu" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="6cB-Al-ASy"/>
                 <constraint firstItem="wVh-0l-AFu" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="6cB-Al-ASy"/>
+                <constraint firstItem="MOK-Ap-tLT" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="CN5-RX-Veu"/>
                 <constraint firstItem="Ofc-kF-lNX" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="SHl-b2-znG"/>
                 <constraint firstItem="Ofc-kF-lNX" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="SHl-b2-znG"/>
+                <constraint firstItem="MOK-Ap-tLT" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="XX5-a9-CHV"/>
                 <constraint firstItem="wVh-0l-AFu" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="tyc-Iy-wZR"/>
                 <constraint firstItem="wVh-0l-AFu" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="tyc-Iy-wZR"/>
                 <constraint firstItem="Ofc-kF-lNX" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="14" id="wVW-4b-Vj0"/>
                 <constraint firstItem="Ofc-kF-lNX" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="14" id="wVW-4b-Vj0"/>
             </constraints>
             </constraints>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
             <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
             <connections>
             <connections>
+                <outlet property="audioBtnContainer" destination="MOK-Ap-tLT" id="bvP-Da-pr4"/>
                 <outlet property="audioRecordBtn" destination="wVh-0l-AFu" id="85j-KR-mnf"/>
                 <outlet property="audioRecordBtn" destination="wVh-0l-AFu" id="85j-KR-mnf"/>
                 <outlet property="audioViewTitle" destination="Ofc-kF-lNX" id="K6i-qG-CmP"/>
                 <outlet property="audioViewTitle" destination="Ofc-kF-lNX" id="K6i-qG-CmP"/>
             </connections>
             </connections>

+ 21 - 0
o2ios/O2Platform/Assets.xcassets/im/chat_audio_cancel.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "松开@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
o2ios/O2Platform/Assets.xcassets/im/chat_audio_cancel.imageset/松开@3x.png


+ 21 - 0
o2ios/O2Platform/Assets.xcassets/im/chat_audio_voice.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "语音 6@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
o2ios/O2Platform/Assets.xcassets/im/chat_audio_voice.imageset/语音 6@3x.png