Compare commits

...

3 Commits

Author SHA1 Message Date
Fin
c1d9dfe7f6 优化图片未加载时导致的布局问题 2025-05-27 10:43:05 +08:00
Fin
fb252f20c9 修复复用导致的布局错误 2025-05-27 10:12:59 +08:00
uuneo
30a9f51236 add AudioToCAF 2025-05-23 14:00:50 +08:00
2 changed files with 84 additions and 9 deletions

View File

@ -186,10 +186,8 @@ extension SoundsViewController: UIDocumentPickerDelegate {
/// caf
func pickerSoundFile() {
if #available(iOS 14.0, *) {
let types = UTType.types(tag: "caf",
tagClass: UTTagClass.filenameExtension,
conformingTo: nil)
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: types)
/// .audio iOS
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.audio])
documentPicker.delegate = self
documentPicker.allowsMultipleSelection = false
documentPicker.modalPresentationStyle = .pageSheet
@ -208,8 +206,58 @@ extension SoundsViewController: UIDocumentPickerDelegate {
let fileCoordinator = NSFileCoordinator()
let err = NSErrorPointer(nilLiteral: ())
fileCoordinator.coordinate(readingItemAt: url, error: err) { url in
self.importSoundActionRelay.accept(url)
// caf
if url.pathExtension.lowercased() == "caf" {
// caf
self.importSoundActionRelay.accept(url)
} else {
// caf caf
convertAudioToCAF(inputURL: url) { url in
if let url {
//
self.importSoundActionRelay.accept(url)
}
}
}
}
url.stopAccessingSecurityScopedResource()
}
/// CAF
/// - Parameters:
/// - inputURL: URL
/// - completion: CAF URL nil
func convertAudioToCAF(inputURL: URL, completion: @escaping (URL?) -> Void) {
let fileName = inputURL.deletingPathExtension().lastPathComponent
let outputURL = FileManager.default.temporaryDirectory.appendingPathComponent("\(fileName).caf")
do {
if FileManager.default.fileExists(atPath: outputURL.path) {
try FileManager.default.removeItem(at: outputURL)
}
let asset = AVAsset(url: inputURL)
guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough) else {
completion(nil)
return
}
let maxDuration = CMTime(seconds: 29.9, preferredTimescale: 600)
if asset.duration > maxDuration {
exportSession.timeRange = CMTimeRange(start: .zero, duration: maxDuration)
}
exportSession.outputFileType = .caf
exportSession.outputURL = outputURL
exportSession.exportAsynchronously {
DispatchQueue.main.async {
completion(exportSession.status == .completed ? outputURL : nil)
}
}
} catch {
completion(nil)
}
}
}

View File

@ -40,7 +40,7 @@ class MessageItemView: UIView {
let imageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.contentMode = .scaleAspectFit
imageView.layer.cornerRadius = 4
imageView.clipsToBounds = true
return imageView
@ -168,10 +168,16 @@ extension MessageItemView {
self.dateLabel.text = message.dateText
if let image = message.image {
imageView.isHidden = false
// 使
remakeImageViewConstraints(width: 200, height: 100)
//
imageView.removeImageViewer()
// loadDiskFileSynchronously
imageView.kf.setImage(with: URL(string: image), options: [.targetCache(imageCache), .keepCurrentImageWhileLoading, .loadDiskFileSynchronously]) { [weak self] result in
guard let self else { return }
guard let image = try? result.get().image else {
self.imageView.image = nil
return
}
@ -179,12 +185,13 @@ extension MessageItemView {
let isDarkMode = UIScreen.main.traitCollection.userInterfaceStyle == .dark
var options: [ImageViewerOption] = [
.closeIcon(UIImage(named: "back")!),
.theme(isDarkMode ? .dark : .light)
.theme(isDarkMode ? .dark : .light),
.contentMode(.scaleAspectFit)
]
if #available(iOS 14.0, *) {
options.append(.rightNavItemTitle(NSLocalizedString("save"), onTap: { _ in
options.append(.rightNavItemTitle(NSLocalizedString("save"), onTap: { [weak self] _ in
// image
self.saveImageToAlbum(image)
self?.saveImageToAlbum(image)
}))
}
self.imageView.setupImageViewer(options: options)
@ -193,6 +200,7 @@ extension MessageItemView {
}
} else {
imageView.isHidden = true
remakeImageViewConstraints(width: 0, height: 0)
}
}
@ -207,6 +215,10 @@ extension MessageItemView {
height = 400
}
remakeImageViewConstraints(width: width, height: height)
}
func remakeImageViewConstraints(width: CGFloat, height: CGFloat) {
imageView.snp.remakeConstraints { make in
make.width.equalTo(width)
make.height.equalTo(height)
@ -238,3 +250,18 @@ extension MessageItemView {
}
}
}
extension UIImageView {
func removeImageViewer() {
var _tapRecognizer: UIGestureRecognizer?
gestureRecognizers?.forEach {
// TapWithDataRecognizer
if "\(type(of: $0))" == "TapWithDataRecognizer" {
_tapRecognizer = $0
}
}
if let _tapRecognizer {
self.removeGestureRecognizer(_tapRecognizer)
}
}
}