Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
zhangyongji
/
MRFramework
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Members
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
634a14d2
authored
Sep 09, 2019
by
Sarkizz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加图片多选
parent
52a7a3fa
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
193 additions
and
10 deletions
+193
-10
MRFramework/MRFramework.xcodeproj/project.pbxproj
+4
-0
MRFramework/MRFramework/UIControls/Album/MRAlbumListViewController.swift
+95
-8
MRFramework/MRFramework/UIControls/PhotoPicker/SAMutableSelectionAlbum.swift
+76
-0
MRFramework/MRFramework/UIControls/PhotoPicker/SAPhotoPicker.swift
+18
-2
No files found.
MRFramework/MRFramework.xcodeproj/project.pbxproj
View file @
634a14d2
...
...
@@ -17,6 +17,7 @@
A70210522320FE8B009F8BC6
/* MRAlbumListViewController.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A702104E2320FE8B009F8BC6
/* MRAlbumListViewController.swift */
;
};
A70210532320FE8B009F8BC6
/* MRAlbumCell.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A70210502320FE8B009F8BC6
/* MRAlbumCell.swift */
;
};
A70210542320FE8B009F8BC6
/* MRCheckBoxImage.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A70210512320FE8B009F8BC6
/* MRCheckBoxImage.swift */
;
};
A702105823225148009F8BC6
/* SAMutableSelectionAlbum.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A702105723225148009F8BC6
/* SAMutableSelectionAlbum.swift */
;
};
A73E5C8F23136605000C379B
/* UIColor+util.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A73E5C8E23136605000C379B
/* UIColor+util.swift */
;
};
A73E5C922313767C000C379B
/* UIButton+util.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A73E5C912313767C000C379B
/* UIButton+util.swift */
;
};
A73E5C95231376D6000C379B
/* NamespaceWrappable.swift in Sources */
=
{
isa
=
PBXBuildFile
;
fileRef
=
A73E5C94231376D6000C379B
/* NamespaceWrappable.swift */
;
};
...
...
@@ -74,6 +75,7 @@
A702104E2320FE8B009F8BC6
/* MRAlbumListViewController.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MRAlbumListViewController.swift
;
sourceTree
=
"<group>"
;
};
A70210502320FE8B009F8BC6
/* MRAlbumCell.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MRAlbumCell.swift
;
sourceTree
=
"<group>"
;
};
A70210512320FE8B009F8BC6
/* MRCheckBoxImage.swift */
=
{
isa
=
PBXFileReference
;
fileEncoding
=
4
;
lastKnownFileType
=
sourcecode.swift
;
path
=
MRCheckBoxImage.swift
;
sourceTree
=
"<group>"
;
};
A702105723225148009F8BC6
/* SAMutableSelectionAlbum.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
SAMutableSelectionAlbum.swift
;
sourceTree
=
"<group>"
;
};
A73E5C8E23136605000C379B
/* UIColor+util.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"UIColor+util.swift"
;
sourceTree
=
"<group>"
;
};
A73E5C912313767C000C379B
/* UIButton+util.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
"UIButton+util.swift"
;
sourceTree
=
"<group>"
;
};
A73E5C94231376D6000C379B
/* NamespaceWrappable.swift */
=
{
isa
=
PBXFileReference
;
lastKnownFileType
=
sourcecode.swift
;
path
=
NamespaceWrappable.swift
;
sourceTree
=
"<group>"
;
};
...
...
@@ -335,6 +337,7 @@
isa
=
PBXGroup
;
children
=
(
A7B8E160230E319700999DF2
/* SAPhotoPicker.swift */
,
A702105723225148009F8BC6
/* SAMutableSelectionAlbum.swift */
,
);
path
=
PhotoPicker
;
sourceTree
=
"<group>"
;
...
...
@@ -545,6 +548,7 @@
A73E5C97231377CD000C379B
/* UITableView+reusable.swift in Sources */
,
A7B8E15D230E318400999DF2
/* BLEManager.swift in Sources */
,
A7021016231CC60C009F8BC6
/* MRScanningProtocol.swift in Sources */
,
A702105823225148009F8BC6
/* SAMutableSelectionAlbum.swift in Sources */
,
A7B8E161230E319700999DF2
/* SAPhotoPicker.swift in Sources */
,
A7021017231CC60C009F8BC6
/* MRScanningLineView.swift in Sources */
,
A702101B231CC60C009F8BC6
/* ScanningAVManager.swift in Sources */
,
...
...
MRFramework/MRFramework/UIControls/Album/MRAlbumListViewController.swift
View file @
634a14d2
...
...
@@ -92,6 +92,15 @@ open class MRAlbumListViewController: UIViewController {
thumbImageSize
=
layout
?
.
itemSize
??
CGSize
.
zero
}
open
func
cellSetting
(
_
cell
:
UICollectionViewCell
,
at
indexPath
:
IndexPath
)
{
if
let
cell
=
cell
as?
MRAlbumCell
,
let
assest
=
assests
?[
indexPath
.
row
]
{
requestImage
(
with
:
assest
,
size
:
thumbImageSize
*
UIScreen
.
main
.
scale
)
{
image
,
info
in
cell
.
setImage
(
image
)
}
cell
.
isSelected
=
selectedAssests
.
contains
(
assest
)
}
}
open
func
addNavButtonIfNeeded
()
{
if
let
nav
=
navigationController
,
nav
.
viewControllers
[
0
]
==
self
{
...
...
@@ -126,12 +135,94 @@ open class MRAlbumListViewController: UIViewController {
}
extension
MRAlbumListViewController
{
public
func
requestImage
(
with
assest
:
PHAsset
,
size
:
CGSize
,
completion
:
@escaping
(
_
image
:
UIImage
?)
->
Void
)
{
imageCache
.
requestImage
(
for
:
assest
,
targetSize
:
size
,
contentMode
:
.
aspectFill
,
options
:
nil
)
{
(
image
,
info
)
in
@discardableResult
public
func
requestImage
(
with
assest
:
PHAsset
,
size
:
CGSize
?
=
nil
,
completion
:
@escaping
(
_
image
:
UIImage
?,
_
isTempImage
:
Bool
)
->
Void
)
->
PHImageRequestID
{
let
finish
:
(
_
image
:
UIImage
?,
_
info
:
[
AnyHashable
:
Any
]?)
->
Void
=
{
image
,
info
in
DispatchQueue
.
main
.
async
{
completion
(
image
)
let
degrade
=
info
?[
PHImageResultIsDegradedKey
]
as?
NSNumber
let
isTemp
=
degrade
?
.
boolValue
??
true
completion
(
image
,
isTemp
)
}
}
let
options
=
PHImageRequestOptions
()
options
.
isNetworkAccessAllowed
=
true
if
let
size
=
size
{
return
imageCache
.
requestImage
(
for
:
assest
,
targetSize
:
size
,
contentMode
:
.
aspectFill
,
options
:
options
,
resultHandler
:
finish
)
}
else
{
return
imageCache
.
requestImage
(
for
:
assest
,
targetSize
:
PHImageManagerMaximumSize
,
contentMode
:
.
default
,
options
:
options
,
resultHandler
:
finish
)
}
}
public
func
requestImages
(
with
assests
:
[
PHAsset
],
size
:
CGSize
?
=
nil
,
inQueue
:
DispatchQueue
=
DispatchQueue
.
global
(),
progress
:
((
_
progress
:
Float
)
->
Void
)?
=
nil
,
completion
:
@escaping
(
_
images
:
[
UIImage
]?,
_
error
:
String
?)
->
Void
)
{
var
count
=
assests
.
count
var
images
=
[
UIImage
]()
var
requestIDs
=
[
PHImageRequestID
]()
let
finish
:
(
_
image
:
UIImage
?,
_
info
:
[
AnyHashable
:
Any
]?)
->
Void
=
{
image
,
info
in
//移除已完成的id
if
let
idNum
=
info
?[
PHImageResultRequestIDKey
]
as?
NSNumber
{
requestIDs
.
removeAll
(
where
:
{
$0
==
idNum
.
int32Value
})
}
//每个图片请求完成的操作
if
let
image
=
image
{
images
.
append
(
image
)
count
-=
1
}
else
{
//若其中一个请求失败,直接中断所有请求任务
let
error
=
info
?[
PHImageErrorKey
]
as?
String
??
"获取图片失败"
completion
(
nil
,
error
)
count
=
assests
.
count
requestIDs
.
forEach
({
self
.
imageCache
.
cancelImageRequest
(
$0
)
})
}
DispatchQueue
.
main
.
async
{
progress
?(
Float
((
assests
.
count
-
count
)
/
assests
.
count
))
if
count
<=
0
{
completion
(
images
,
nil
)
}
}
}
let
options
=
PHImageRequestOptions
()
options
.
isNetworkAccessAllowed
=
true
options
.
isSynchronous
=
true
progress
?(
0
)
inQueue
.
async
{
assests
.
forEach
({
a
in
if
let
size
=
size
{
self
.
imageCache
.
requestImage
(
for
:
a
,
targetSize
:
size
,
contentMode
:
.
aspectFill
,
options
:
options
,
resultHandler
:
{
(
image
,
info
)
in
finish
(
image
,
info
)
})
}
else
{
self
.
imageCache
.
requestImage
(
for
:
a
,
targetSize
:
PHImageManagerMaximumSize
,
contentMode
:
.
default
,
options
:
options
,
resultHandler
:
{
(
image
,
info
)
in
finish
(
image
,
info
)
})
}
})
}
}
}
...
...
@@ -245,11 +336,7 @@ extension MRAlbumListViewController: UICollectionViewDataSource {
open
func
collectionView
(
_
collectionView
:
UICollectionView
,
cellForItemAt
indexPath
:
IndexPath
)
->
UICollectionViewCell
{
let
cell
=
collectionView
.
mr
.
dequeueCell
(
MRAlbumCell
.
self
,
for
:
indexPath
)
if
let
assest
=
assests
?[
indexPath
.
row
]
{
requestImage
(
with
:
assest
,
size
:
thumbImageSize
*
UIScreen
.
main
.
scale
)
{
(
image
)
in
cell
.
setImage
(
image
)
}
}
cellSetting
(
cell
,
at
:
indexPath
)
return
cell
}
}
...
...
MRFramework/MRFramework/UIControls/PhotoPicker/SAMutableSelectionAlbum.swift
0 → 100644
View file @
634a14d2
//
// SAMutableSelectionAlbum.swift
// MRFramework
//
// Created by Sarkizz on 2019/9/6.
// Copyright © 2019 sarkizz. All rights reserved.
//
import
Foundation
public
class
SAMutableSelectionAlbum
:
MRAlbumListViewController
{
public
var
maxCount
=
1
{
didSet
{
resetSelection
()
}
}
public
var
maxImageSize
:
CGSize
?
public
var
didFinish
:
((
_
vc
:
SAMutableSelectionAlbum
,
_
images
:
[
UIImage
])
->
Void
)?
public
override
func
confirm
()
{
ToastView
.
loading
()
requestImages
(
with
:
selectedAssests
)
{
(
images
,
error
)
in
ToastView
.
hide
(
animate
:
false
)
if
let
images
=
images
{
self
.
didFinish
?(
self
,
images
)
}
else
{
let
error
=
error
??
"获取图片失败"
ToastView
.
show
(
error
)
}
}
}
public
override
func
cellSetting
(
_
cell
:
UICollectionViewCell
,
at
indexPath
:
IndexPath
)
{
if
let
cell
=
cell
as?
MRAlbumCell
{
cell
.
checkbox
.
isUserInteractionEnabled
=
false
}
}
}
extension
SAMutableSelectionAlbum
{
private
func
resetSelection
()
{
if
maxCount
<=
0
{
collectionView
.
allowsSelection
=
false
selectedAssests
.
removeAll
()
}
else
{
collectionView
.
allowsSelection
=
true
collectionView
.
allowsMultipleSelection
=
maxCount
>
1
let
count
=
selectedAssests
.
count
-
maxCount
if
count
>
0
{
selectedAssests
.
removeLast
(
count
)
}
}
collectionView
.
reloadData
()
}
}
extension
SAMutableSelectionAlbum
{
public
override
func
collectionView
(
_
collectionView
:
UICollectionView
,
didSelectItemAt
indexPath
:
IndexPath
)
{
if
selectedAssests
.
count
>=
maxCount
{
collectionView
.
deselectItem
(
at
:
indexPath
,
animated
:
false
)
return
}
selectedAssests
.
append
(
assests
!
[
indexPath
.
row
])
if
!
collectionView
.
allowsMultipleSelection
{
confirm
()
}
}
public
func
collectionView
(
_
collectionView
:
UICollectionView
,
didDeselectItemAt
indexPath
:
IndexPath
)
{
if
let
assest
=
assests
?[
indexPath
.
row
]
{
selectedAssests
.
removeAll
(
where
:
{
$0
==
assest
})
}
}
}
MRFramework/MRFramework/UIControls/PhotoPicker/SAPhotoPicker.swift
View file @
634a14d2
...
...
@@ -14,9 +14,10 @@ public enum SAPhotoPickerType {
case
camera
case
photo
case
savedPhotosAlbum
case
custom
(
count
:
Int
)
}
public
typealias
SAPhotoPickerComplateBlock
=
(
_
image
:
UIImage
?,
_
imageURL
:
URL
?,
_
error
:
Error
?)
->
Void
public
typealias
SAPhotoPickerComplateBlock
=
(
_
image
s
:
[
UIImage
]?,
_
imageURLs
:
[
URL
]
?,
_
error
:
Error
?)
->
Void
extension
SAPhotoPicker
{
//config keys
...
...
@@ -74,6 +75,9 @@ public class SAPhotoPicker: NSObject {
case
.
savedPhotosAlbum
:
self
.
showImagePicker
(
.
savedPhotosAlbum
)
break
case
.
custom
(
let
count
):
self
.
showCustomAlbum
(
count
)
break
}
}
}
...
...
@@ -88,6 +92,17 @@ extension SAPhotoPicker {
UIApplication
.
shared
.
keyWindow
?
.
rootViewController
?
.
present
(
vc
,
animated
:
true
,
completion
:
nil
)
}
private
func
showCustomAlbum
(
_
count
:
Int
)
{
let
vc
=
SAMutableSelectionAlbum
()
vc
.
title
=
config
[
.
albumTitle
]
as?
String
vc
.
maxCount
=
count
vc
.
didFinish
=
{
vc
,
images
in
self
.
complateBlock
?(
images
,
nil
,
nil
)
vc
.
dismiss
(
animated
:
true
)
}
UIApplication
.
shared
.
keyWindow
?
.
rootViewController
?
.
present
(
vc
,
animated
:
true
,
completion
:
nil
)
}
private
func
navTitle
(
with
sourceType
:
UIImagePickerController
.
SourceType
)
->
String
?
{
switch
sourceType
{
case
.
camera
:
...
...
@@ -116,7 +131,8 @@ extension SAPhotoPicker: UINavigationControllerDelegate, UIImagePickerController
}
if
let
image
=
image
{
complateBlock
?(
image
,
info
[
.
referenceURL
]
as?
URL
,
nil
)
let
url
=
info
[
.
referenceURL
]
as?
URL
complateBlock
?([
image
],
url
==
nil
?
nil
:
[
url
!
],
nil
)
}
else
{
complateBlock
?(
nil
,
nil
,
error
(
code
:
-
1
,
msg
:
"获取图片失败"
))
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment