Skip to content

Commit 2728b3d

Browse files
committed
feat: add bundle file for Viewer / doing custom header for preview view
1 parent 27c8ef3 commit 2728b3d

34 files changed

+184
-202
lines changed

Preview/PreviewHeader.swift

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import UIKit
2+
3+
protocol PreviewHeaderViewDelegate: AnyObject {
4+
func headerView(_ headerView: PreviewHeaderView, didPressClearButton button: UIButton)
5+
func headerView(_ headerView: PreviewHeaderView, didPressDoneButton button: UIButton)
6+
}
7+
8+
class PreviewHeaderView: UIView {
9+
weak var viewDelegate: PreviewHeaderViewDelegate?
10+
static let ButtonSize = CGFloat(24.0)
11+
static let TopMargin = CGFloat(15.0)
12+
13+
lazy var clearButton: UIButton = {
14+
let image = UIImage.close
15+
16+
let button = UIButton(type: .custom)
17+
button.setImage(image, for: .normal)
18+
button.addTarget(self, action: #selector(PreviewHeaderView.clearAction(button:)), for: .touchUpInside)
19+
20+
return button
21+
}()
22+
23+
lazy var doneButton: UIButton = {
24+
let image = UIImage.play
25+
26+
let button = UIButton(type: .custom)
27+
button.setImage(image, for: .normal)
28+
button.addTarget(self, action: #selector(PreviewHeaderView.clearAction(button:)), for: .touchUpInside)
29+
30+
return button
31+
}()
32+
33+
override init(frame: CGRect) {
34+
super.init(frame: frame)
35+
36+
let stackView = UIStackView()
37+
stackView.translatesAutoresizingMaskIntoConstraints = false
38+
stackView.axis = .horizontal
39+
stackView.distribution = .equalSpacing // Đặt phân bố để căn chỉnh giữa
40+
addSubview(stackView)
41+
42+
// Tạo hai UIView là các mục trong header row
43+
self.clearButton.translatesAutoresizingMaskIntoConstraints = false
44+
stackView.addArrangedSubview(self.clearButton)
45+
46+
self.doneButton.translatesAutoresizingMaskIntoConstraints = false
47+
stackView.addArrangedSubview(self.doneButton)
48+
49+
// Đặt constraints cho stack view để căn chỉnh theo phía trái và phải
50+
NSLayoutConstraint.activate([
51+
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
52+
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
53+
stackView.topAnchor.constraint(equalTo: topAnchor),
54+
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
55+
])
56+
}
57+
58+
@available(*, unavailable)
59+
required init?(coder _: NSCoder) {
60+
fatalError("init(coder:) has not been implemented")
61+
}
62+
63+
override func layoutSubviews() {
64+
super.layoutSubviews()
65+
}
66+
67+
@objc func clearAction(button: UIButton) {
68+
self.viewDelegate?.headerView(self, didPressClearButton: button)
69+
}
70+
71+
@objc func doneAction(button: UIButton) {
72+
self.viewDelegate?.headerView(self, didPressDoneButton: button)
73+
}
74+
}

Preview/PreviewItem.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// ViewerPhoto.swift
3+
// react-native-multiple-image-picker
4+
//
5+
// Created by BẢO HÀ on 10/09/2023.
6+
//
7+
8+
import Photos
9+
import TLPhotoPicker
10+
import UIKit
11+
12+
class PreviewItem: Viewable {
13+
var placeholder = UIImage()
14+
15+
enum Size {
16+
case small
17+
case large
18+
}
19+
20+
var type: ViewableType = .image
21+
var id: String
22+
var url: String?
23+
var assetID: String?
24+
25+
init(id: String) {
26+
self.id = id
27+
}
28+
29+
func media(_ completion: @escaping (_ image: UIImage?, _ error: NSError?) -> Void) {
30+
if let assetID = self.assetID {
31+
if let asset = PHAsset.fetchAssets(withLocalIdentifiers: [assetID], options: nil).firstObject {
32+
PreviewItem.image(for: asset) { image in
33+
completion(image, nil)
34+
}
35+
}
36+
} else {
37+
completion(self.placeholder, nil)
38+
}
39+
}
40+
41+
static func image(for asset: PHAsset, completion: @escaping (_ image: UIImage?) -> Void) {
42+
let imageManager = PHImageManager.default()
43+
let requestOptions = PHImageRequestOptions()
44+
requestOptions.isNetworkAccessAllowed = true
45+
requestOptions.isSynchronous = false
46+
requestOptions.deliveryMode = .opportunistic
47+
requestOptions.resizeMode = .fast
48+
49+
let bounds = UIScreen.main.bounds.size
50+
let targetSize = CGSize(width: bounds.width * 2, height: bounds.height * 2)
51+
imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFit, options: requestOptions) { image, _ in
52+
// WARNING: This could fail if your phone doesn't have enough storage. Since the photo is probably
53+
// stored in iCloud downloading it to your phone will take most of the space left making this feature fail.
54+
// guard let image = image else { fatalError("Couldn't get photo data for asset \(asset)") }
55+
DispatchQueue.main.async {
56+
completion(image)
57+
}
58+
}
59+
}
60+
}

example/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ SPEC CHECKSUMS:
618618
React-jsiexecutor: 1579bf3207afadc72ac3638a66a102d1bf5263e3
619619
React-jsinspector: 14a342151ab810862998dfc99e2720746734e9b3
620620
React-logger: 94ec392ae471683635e4bf874d4e82f675399d2d
621-
react-native-multiple-image-picker: 23e5c68a29e7aa0429a04ac4ac19c9105b79fbff
621+
react-native-multiple-image-picker: bf07238dbbd6ba7928f01705d85584ac0d7b27a1
622622
React-perflogger: 883a55a9a899535eaf06d0029108ef9ef22cce92
623623
React-RCTActionSheet: 1a3b8416688a3d291367be645022886f71d6842a
624624
React-RCTAnimation: e5560cb72d91ba35151d51e2eb0d467b42763f43

ios/CustomPhotoPicker/CustomPhotoPickerViewController.swift

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import Foundation
1010
import TLPhotoPicker
1111

1212
class CustomPhotoPickerViewController: TLPhotosPickerViewController, ViewerControllerDataSource {
13-
func numberOfItemsInViewerController(_ viewerController: ViewerController) -> Int {
13+
var viewerController: ViewerController?
14+
15+
func numberOfItemsInViewerController(_: ViewerController) -> Int {
1416
var count = 0
1517

1618
for section in 0 ..< collectionView.numberOfSections {
@@ -20,8 +22,8 @@ class CustomPhotoPickerViewController: TLPhotosPickerViewController, ViewerContr
2022
return count
2123
}
2224

23-
func viewerController(_ viewerController: ViewerController, viewableAt indexPath: IndexPath) -> Viewable {
24-
let viewable = ViewerPhoto(id: UUID().uuidString)
25+
func viewerController(_: ViewerController, viewableAt indexPath: IndexPath) -> Viewable {
26+
let viewable = PreviewItem(id: UUID().uuidString)
2527

2628
if let cell = collectionView?.cellForItem(at: indexPath) as? Cell, let placeholder = cell.imageView?.image, let asset = cell.asset {
2729
viewable.assetID = asset.localIdentifier
@@ -49,11 +51,16 @@ class CustomPhotoPickerViewController: TLPhotosPickerViewController, ViewerContr
4951
@objc func handleCellLongPress(_ notification: Notification) {
5052
if let cell = notification.object as? Cell {
5153
if let indexPath = collectionView.indexPath(for: cell) {
52-
let viewerController = ViewerController(initialIndexPath: indexPath, collectionView: collectionView)
54+
self.viewerController = ViewerController(initialIndexPath: indexPath, collectionView: collectionView)
55+
56+
self.viewerController!.dataSource = self
5357

54-
viewerController.dataSource = self
58+
let headerView = PreviewHeaderView()
59+
headerView.viewDelegate = self
5560

56-
self.present(viewerController, animated: true, completion: nil)
61+
self.viewerController!.headerView = headerView
62+
63+
self.present(self.viewerController!, animated: true, completion: nil)
5764
}
5865
}
5966
}
@@ -82,7 +89,7 @@ class CustomPhotoPickerViewController: TLPhotosPickerViewController, ViewerContr
8289
}
8390
}
8491

85-
func cellOnLongPress(_ cell: Cell) {
92+
func cellOnLongPress(_: Cell) {
8693
//
8794
}
8895

@@ -95,3 +102,16 @@ class CustomPhotoPickerViewController: TLPhotosPickerViewController, ViewerContr
95102
super.viewWillDisappear(animated)
96103
}
97104
}
105+
106+
extension CustomPhotoPickerViewController: PreviewHeaderViewDelegate {
107+
func headerView(_: PreviewHeaderView, didPressClearButton _: UIButton) {
108+
self.viewerController?.dismiss(nil)
109+
}
110+
111+
func headerView(_: PreviewHeaderView, didDoneMenuButton _: UIButton) {
112+
// let rect = CGRect(x: 0, y: 0, width: 50, height: 50)
113+
// self.optionsController = OptionsController(sourceView: button, sourceRect: rect)
114+
// self.optionsController!.delegate = self
115+
// self.viewerController?.present(self.optionsController!, animated: true, completion: nil)
116+
}
117+
}

ios/MultipleImagePicker.bundle/Viewer.xcassets/Contents.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

ios/MultipleImagePicker.bundle/Viewer.xcassets/close.imageset/Contents.json

Lines changed: 0 additions & 23 deletions
This file was deleted.
Binary file not shown.
Binary file not shown.
Binary file not shown.

ios/MultipleImagePicker.bundle/Viewer.xcassets/dark-circle.imageset/Contents.json

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)