소스 검색

Merge branch 'feature/dev_Chris' into develop

Chris 5 년 전
부모
커밋
2ac2407f2e

+ 36 - 0
RainbowPlanet/RainbowPlanet.xcodeproj/project.pbxproj

@@ -323,6 +323,13 @@
 		A7FF159C228D9E3D00A85748 /* OrderRefundDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7FF159B228D9E3C00A85748 /* OrderRefundDetailModel.swift */; };
 		BD09C84122955B480080D5A4 /* PopTopTriangleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD09C84022955B480080D5A4 /* PopTopTriangleView.swift */; };
 		BD0E678522A4C23B00B980BA /* ShoppingCartOrderPayFreightCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD0E678422A4C23B00B980BA /* ShoppingCartOrderPayFreightCell.swift */; };
+		BD108C9322A60C2100837DAB /* HGImageCompleteButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C8E22A60C2100837DAB /* HGImageCompleteButton.swift */; };
+		BD108C9422A60C2100837DAB /* HGImageCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C8F22A60C2100837DAB /* HGImageCollectionViewController.swift */; };
+		BD108C9522A60C2100837DAB /* HGImageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C9022A60C2100837DAB /* HGImageCollectionViewCell.swift */; };
+		BD108C9622A60C2100837DAB /* HGImagePickerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C9122A60C2100837DAB /* HGImagePickerCell.swift */; };
+		BD108C9722A60C2100837DAB /* HGImagePickerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD108C9222A60C2100837DAB /* HGImagePickerController.swift */; };
+		BD108C9A22A60C3300837DAB /* HGImage.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = BD108C9822A60C3200837DAB /* HGImage.xcassets */; };
+		BD108C9B22A60C3300837DAB /* HGImage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BD108C9922A60C3300837DAB /* HGImage.storyboard */; };
 		BD1DC6C5228CFD0B00B89C57 /* SwiftMoyaNetWorkServiceOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1DC6C3228CFD0B00B89C57 /* SwiftMoyaNetWorkServiceOrder.swift */; };
 		BD1DC6C6228CFD0B00B89C57 /* SwiftMoyaServiceOrderApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1DC6C4228CFD0B00B89C57 /* SwiftMoyaServiceOrderApi.swift */; };
 		BD1DC6C9228D005000B89C57 /* OrderCreateParameterModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD1DC6C8228D005000B89C57 /* OrderCreateParameterModel.swift */; };
@@ -727,6 +734,13 @@
 		A7FF159B228D9E3C00A85748 /* OrderRefundDetailModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OrderRefundDetailModel.swift; sourceTree = "<group>"; };
 		BD09C84022955B480080D5A4 /* PopTopTriangleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PopTopTriangleView.swift; sourceTree = "<group>"; };
 		BD0E678422A4C23B00B980BA /* ShoppingCartOrderPayFreightCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCartOrderPayFreightCell.swift; sourceTree = "<group>"; };
+		BD108C8E22A60C2100837DAB /* HGImageCompleteButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImageCompleteButton.swift; sourceTree = "<group>"; };
+		BD108C8F22A60C2100837DAB /* HGImageCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImageCollectionViewController.swift; sourceTree = "<group>"; };
+		BD108C9022A60C2100837DAB /* HGImageCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImageCollectionViewCell.swift; sourceTree = "<group>"; };
+		BD108C9122A60C2100837DAB /* HGImagePickerCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImagePickerCell.swift; sourceTree = "<group>"; };
+		BD108C9222A60C2100837DAB /* HGImagePickerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HGImagePickerController.swift; sourceTree = "<group>"; };
+		BD108C9822A60C3200837DAB /* HGImage.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = HGImage.xcassets; sourceTree = "<group>"; };
+		BD108C9922A60C3300837DAB /* HGImage.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = HGImage.storyboard; sourceTree = "<group>"; };
 		BD1DC6C3228CFD0B00B89C57 /* SwiftMoyaNetWorkServiceOrder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftMoyaNetWorkServiceOrder.swift; sourceTree = "<group>"; };
 		BD1DC6C4228CFD0B00B89C57 /* SwiftMoyaServiceOrderApi.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftMoyaServiceOrderApi.swift; sourceTree = "<group>"; };
 		BD1DC6C8228D005000B89C57 /* OrderCreateParameterModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderCreateParameterModel.swift; sourceTree = "<group>"; };
@@ -2181,6 +2195,7 @@
 		A77F2CBC2232022A001BD3F6 /* Tools */ = {
 			isa = PBXGroup;
 			children = (
+				BD108C8D22A60A2000837DAB /* HGImagePicker */,
 				A7391212229F75F50033177E /* JXPagingView-Swift */,
 				A7146346228EFCE20066099B /* SKUDataFilter */,
 				A7274C51228EE635000E3A07 /* SwiftScan */,
@@ -2866,6 +2881,20 @@
 			path = ViewController;
 			sourceTree = "<group>";
 		};
+		BD108C8D22A60A2000837DAB /* HGImagePicker */ = {
+			isa = PBXGroup;
+			children = (
+				BD108C9222A60C2100837DAB /* HGImagePickerController.swift */,
+				BD108C9122A60C2100837DAB /* HGImagePickerCell.swift */,
+				BD108C8F22A60C2100837DAB /* HGImageCollectionViewController.swift */,
+				BD108C9022A60C2100837DAB /* HGImageCollectionViewCell.swift */,
+				BD108C8E22A60C2100837DAB /* HGImageCompleteButton.swift */,
+				BD108C9922A60C3300837DAB /* HGImage.storyboard */,
+				BD108C9822A60C3200837DAB /* HGImage.xcassets */,
+			);
+			path = HGImagePicker;
+			sourceTree = "<group>";
+		};
 		BD1DC6C2228CFD0B00B89C57 /* SwiftMoyaServiceOrder */ = {
 			isa = PBXGroup;
 			children = (
@@ -3227,9 +3256,11 @@
 				A7190167227543DB00104A50 /* baidu_cityid_rel.json in Resources */,
 				A77F2C682231FB4A001BD3F6 /* Assets.xcassets in Resources */,
 				A72C01232275404A0065E0C3 /* province_city_area.json in Resources */,
+				BD108C9B22A60C3300837DAB /* HGImage.storyboard in Resources */,
 				A7FF1577228C824300A85748 /* OrderModule.xcassets in Resources */,
 				BD20F1D82283D2AA00677D8E /* ShoppingCartModule.xcassets in Resources */,
 				A7778C9922438F5D00C7C47A /* README.txt in Resources */,
+				BD108C9A22A60C3300837DAB /* HGImage.xcassets in Resources */,
 				A729B5AA2266F6FD004AE098 /* Launch Screen.storyboard in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -3394,6 +3425,7 @@
 				A72A72BE22321DE000B21995 /* Extension+RxTimer.swift in Sources */,
 				A7CC74EA22706ACD003C4F38 /* MessageViewController.swift in Sources */,
 				BDF47D7E22827C3F00941AB9 /* ProductSlidingTopBottomCollectionViewCell.swift in Sources */,
+				BD108C9522A60C2100837DAB /* HGImageCollectionViewCell.swift in Sources */,
 				A7FF1589228C854900A85748 /* OrderDetailBottomView.swift in Sources */,
 				BD1DC6C5228CFD0B00B89C57 /* SwiftMoyaNetWorkServiceOrder.swift in Sources */,
 				BD7AB83D228438020030646A /* OrderPayExpressInfoShowCell.swift in Sources */,
@@ -3455,6 +3487,7 @@
 				A70B2C292286D77200B2449F /* ProductDetailProductInfoTableViewCell.swift in Sources */,
 				A72A726822321DBD00B21995 /* UMManager.swift in Sources */,
 				A70B2C042283D06B00B2449F /* ProductFloorFullLeftHeaderCollectionReusableView.swift in Sources */,
+				BD108C9322A60C2100837DAB /* HGImageCompleteButton.swift in Sources */,
 				A7B4E721228151F40012914A /* ProductFloorTitleView.swift in Sources */,
 				A729B5AD2266FF45004AE098 /* BindPhoneNumberView.swift in Sources */,
 				A75C474E22938B3900139C0C /* OrderFreightTableViewCell.swift in Sources */,
@@ -3548,6 +3581,7 @@
 				A70B2C102286A3BC00B2449F /* ProductDetailModel.swift in Sources */,
 				A7A17E5F22A0CEF200B7A77E /* SwiftMoyaNetWorkManagerTools.swift in Sources */,
 				A72A72A922321DE000B21995 /* NumberKeyboard.swift in Sources */,
+				BD108C9422A60C2100837DAB /* HGImageCollectionViewController.swift in Sources */,
 				A70B2C272286C5D600B2449F /* ProductDetailFSPagerViewCell.swift in Sources */,
 				A7FF1585228C847300A85748 /* OrderDetailContactAddressTableViewCell.swift in Sources */,
 				A72A72AA22321DE000B21995 /* Log.swift in Sources */,
@@ -3618,6 +3652,7 @@
 				A738D202225AD6AD00EEE860 /* Extension+UICollectionView.swift in Sources */,
 				A7CC74D6226FF421003C4F38 /* MineNavigationBarView.swift in Sources */,
 				A71AF0BC226F099B001730FE /* ProductHBigTableViewCell.swift in Sources */,
+				BD108C9622A60C2100837DAB /* HGImagePickerCell.swift in Sources */,
 				A7A98E3C228036D7005306E9 /* ShoppingMallCategoryCollectionViewCell.swift in Sources */,
 				A71AF0AA226EDDF5001730FE /* SearchView.swift in Sources */,
 				A7FF1583228C843700A85748 /* OrderDetailExpressSelfMentionTableViewCell.swift in Sources */,
@@ -3643,6 +3678,7 @@
 				A7CC750A22715755003C4F38 /* MessageDetailesViewController.swift in Sources */,
 				BDAA40F7228E947500CF841D /* OrderApplyRefundAccountCell.swift in Sources */,
 				A71AF0B8226EF9EC001730FE /* SearchResultNavigationbarView.swift in Sources */,
+				BD108C9722A60C2100837DAB /* HGImagePickerController.swift in Sources */,
 				BD09C84122955B480080D5A4 /* PopTopTriangleView.swift in Sources */,
 				A70B2C5A22886ADF00B2449F /* ShopViewController.swift in Sources */,
 				BDF862AE228E57E1000DEF84 /* OrderCommentDefaultCollectionCell.swift in Sources */,

+ 11 - 8
RainbowPlanet/RainbowPlanet/Modules/OrderModule/OrderApplyRefund/ViewController/OrderApplyRefundController.swift

@@ -9,6 +9,7 @@
 import UIKit
 import RxSwift
 import SwiftyJSON
+import Photos
 
 class OrderApplyRefundController: BaseViewController {
     
@@ -194,14 +195,16 @@ extension OrderApplyRefundController : UITableViewDelegate, UITableViewDataSourc
                         
                     }
                 }) { (action) in
-                    PhotoAndCameraManager.shared().authorizePhoto()
-                    PhotoAndCameraManager.shared().photoAndCameraManagerImageBlock = { [weak self] (image) in
-                        if self?.goodsImageArr.count ?? 0 < 3 {
-                            self?.goodsImageArr.append(image)
-                            self?.tableView.reloadData()
-                        } else {
-                            print("------超过最大数量")
-                        }
+                    let curImages: Int = self?.goodsImageArr.count ?? 0
+                    self?.presentHGImagePicker(maxSelected:3-curImages) { (assets) in
+                        for asset in assets {
+                            let imgManager: PHImageManager = PHImageManager()
+                            imgManager.requestImageData(for: asset, options: nil, resultHandler: { (imageData, dataUTI, orientation, info) in
+                                let image = UIImage(data: imageData ?? Data())
+                                self?.goodsImageArr.append(image ?? UIImage())
+                                self?.tableView.reloadData()
+                            })
+                        }                        
                     }
                 }
             }

+ 12 - 9
RainbowPlanet/RainbowPlanet/Modules/OrderModule/OrderComment/ViewController/OrderCommentController.swift

@@ -9,6 +9,7 @@
 import UIKit
 import RxSwift
 import SwiftyJSON
+import Photos
 
 class OrderCommentController: BaseViewController {
     
@@ -36,7 +37,6 @@ class OrderCommentController: BaseViewController {
         super.viewDidLoad()
         setupViews()
         setupData()
-        
     }
     
     override func setupViews() {
@@ -125,14 +125,17 @@ extension OrderCommentController : UITableViewDelegate, UITableViewDataSource {
                     
                 }
             }) { (action) in
-                PhotoAndCameraManager.shared().authorizePhoto()
-                PhotoAndCameraManager.shared().photoAndCameraManagerImageBlock = { [weak self] (image) in
-                    if self?.productArr![indexPath.row].imageArr.count ?? 0 < 6 {
-                        self?.productArr![indexPath.row].imageArr.append(image)
-                        self?.tableView.reloadData()
-                    } else {
-                        print("------超过最大数量")
-                    }
+                // 开始选择照片,最多允许选择6张
+                let curImages: Int = self?.productArr![indexPath.row].imageArr.count ?? 0
+                self?.presentHGImagePicker(maxSelected:6-curImages) { (assets) in
+                    for asset in assets {
+                        let imgManager: PHImageManager = PHImageManager()
+                        imgManager.requestImageData(for: asset, options: nil, resultHandler: { (imageData, dataUTI, orientation, info) in
+                            let image = UIImage(data: imageData ?? Data())
+                            self?.productArr![indexPath.row].imageArr.append(image ?? UIImage())
+                            self?.tableView.reloadData()
+                        })
+                    }                    
                 }
             }
         }

+ 169 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImage.storyboard

@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="T2V-4B-Rlc">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
+        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Image Picker Controller-->
+        <scene sceneID="BVR-mv-Kbb">
+            <objects>
+                <viewController storyboardIdentifier="imagePickerVC" id="T2V-4B-Rlc" customClass="HGImagePickerController" customModule="hangge_1512" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="4Y5-34-3d0"/>
+                        <viewControllerLayoutGuide type="bottom" id="e8n-UT-KXs"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="aed-4U-dCO">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="58" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="695-4F-dam">
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <prototypes>
+                                    <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" rowHeight="58" id="S6N-Q4-drh" customClass="HGImagePickerCell" customModule="hangge_1512" customModuleProvider="target">
+                                        <rect key="frame" x="0.0" y="28" width="375" height="58"/>
+                                        <autoresizingMask key="autoresizingMask"/>
+                                        <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="S6N-Q4-drh" id="akc-Sf-MNq">
+                                            <frame key="frameInset" width="375" height="57"/>
+                                            <autoresizingMask key="autoresizingMask"/>
+                                            <subviews>
+                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mgg-Ea-kOz">
+                                                    <constraints>
+                                                        <constraint firstAttribute="height" constant="21" id="4zA-PW-No0"/>
+                                                    </constraints>
+                                                    <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                                    <nil key="textColor"/>
+                                                    <nil key="highlightedColor"/>
+                                                </label>
+                                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RWG-AS-vSa">
+                                                    <constraints>
+                                                        <constraint firstAttribute="height" constant="21" id="fgt-nn-uS6"/>
+                                                    </constraints>
+                                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                                    <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
+                                                    <nil key="highlightedColor"/>
+                                                </label>
+                                            </subviews>
+                                            <constraints>
+                                                <constraint firstItem="RWG-AS-vSa" firstAttribute="centerY" secondItem="akc-Sf-MNq" secondAttribute="centerY" id="59O-Dh-QO5"/>
+                                                <constraint firstItem="mgg-Ea-kOz" firstAttribute="centerY" secondItem="akc-Sf-MNq" secondAttribute="centerY" id="TeM-3g-ILU"/>
+                                                <constraint firstItem="RWG-AS-vSa" firstAttribute="leading" secondItem="mgg-Ea-kOz" secondAttribute="trailing" id="Zya-OY-Ot1"/>
+                                                <constraint firstItem="mgg-Ea-kOz" firstAttribute="leading" secondItem="akc-Sf-MNq" secondAttribute="leadingMargin" constant="10" id="hNT-C2-Urm"/>
+                                            </constraints>
+                                        </tableViewCellContentView>
+                                        <connections>
+                                            <outlet property="countLabel" destination="RWG-AS-vSa" id="nPe-Jq-cY6"/>
+                                            <outlet property="titleLabel" destination="mgg-Ea-kOz" id="ESQ-1g-rHz"/>
+                                            <segue destination="ybE-mT-bfT" kind="show" identifier="showImages" id="ebb-RO-ekM"/>
+                                        </connections>
+                                    </tableViewCell>
+                                </prototypes>
+                                <connections>
+                                    <outlet property="dataSource" destination="T2V-4B-Rlc" id="HQF-c1-Lyi"/>
+                                    <outlet property="delegate" destination="T2V-4B-Rlc" id="dRG-lB-iaE"/>
+                                </connections>
+                            </tableView>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstItem="695-4F-dam" firstAttribute="leading" secondItem="aed-4U-dCO" secondAttribute="leading" id="Aif-UQ-KT9"/>
+                            <constraint firstItem="e8n-UT-KXs" firstAttribute="top" secondItem="695-4F-dam" secondAttribute="bottom" id="BHA-Da-k82"/>
+                            <constraint firstItem="695-4F-dam" firstAttribute="top" secondItem="aed-4U-dCO" secondAttribute="top" id="JoV-aw-8w7"/>
+                            <constraint firstAttribute="trailing" secondItem="695-4F-dam" secondAttribute="trailing" id="y0e-Ly-dlC"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="tableView" destination="695-4F-dam" id="6zi-4M-d8A"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="Wn1-aW-bIi" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="1048.8" y="547.37631184407803"/>
+        </scene>
+        <!--Image Collection View Controller-->
+        <scene sceneID="xff-8l-RP9">
+            <objects>
+                <viewController storyboardIdentifier="hgImageCollectionVC" id="ybE-mT-bfT" customClass="HGImageCollectionViewController" customModule="hangge_1512" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="eJc-Du-Q6U"/>
+                        <viewControllerLayoutGuide type="bottom" id="Zws-CJ-rtL"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="GVK-7L-Fs8">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="7ZZ-Yj-QTv">
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="1" minimumInteritemSpacing="1" id="rwi-h3-hSX">
+                                    <size key="itemSize" width="80" height="80"/>
+                                    <size key="headerReferenceSize" width="0.0" height="0.0"/>
+                                    <size key="footerReferenceSize" width="0.0" height="0.0"/>
+                                    <inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
+                                </collectionViewFlowLayout>
+                                <cells>
+                                    <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="cell" id="xGF-2R-csA" customClass="HGImageCollectionViewCell" customModule="hangge_1512" customModuleProvider="target">
+                                        <rect key="frame" x="0.0" y="0.0" width="80" height="80"/>
+                                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                                        <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                                            <rect key="frame" x="0.0" y="0.0" width="80" height="80"/>
+                                            <autoresizingMask key="autoresizingMask"/>
+                                            <subviews>
+                                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="6g8-le-Aax"/>
+                                                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="hg_image_not_selected" translatesAutoresizingMaskIntoConstraints="NO" id="ym3-2Y-K4b">
+                                                    <constraints>
+                                                        <constraint firstAttribute="height" constant="30" id="6qL-qA-j3A"/>
+                                                        <constraint firstAttribute="width" constant="30" id="NdX-z7-daj"/>
+                                                    </constraints>
+                                                </imageView>
+                                            </subviews>
+                                        </view>
+                                        <constraints>
+                                            <constraint firstAttribute="trailing" secondItem="6g8-le-Aax" secondAttribute="trailing" id="1CX-YA-gBU"/>
+                                            <constraint firstItem="ym3-2Y-K4b" firstAttribute="top" secondItem="xGF-2R-csA" secondAttribute="top" id="DAm-by-sWR"/>
+                                            <constraint firstAttribute="trailing" secondItem="ym3-2Y-K4b" secondAttribute="trailing" id="EHJ-f5-Sj1"/>
+                                            <constraint firstItem="6g8-le-Aax" firstAttribute="top" secondItem="xGF-2R-csA" secondAttribute="top" id="UDz-lr-IH9"/>
+                                            <constraint firstAttribute="bottom" secondItem="6g8-le-Aax" secondAttribute="bottom" id="hCI-an-B11"/>
+                                            <constraint firstItem="6g8-le-Aax" firstAttribute="leading" secondItem="xGF-2R-csA" secondAttribute="leading" id="iTD-VX-259"/>
+                                        </constraints>
+                                        <connections>
+                                            <outlet property="imageView" destination="6g8-le-Aax" id="Urm-1s-ay6"/>
+                                            <outlet property="selectedIcon" destination="ym3-2Y-K4b" id="evG-eP-buM"/>
+                                        </connections>
+                                    </collectionViewCell>
+                                </cells>
+                                <connections>
+                                    <outlet property="dataSource" destination="ybE-mT-bfT" id="51g-Ey-BQD"/>
+                                    <outlet property="delegate" destination="ybE-mT-bfT" id="DD0-Sh-2Pw"/>
+                                </connections>
+                            </collectionView>
+                            <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BUV-FR-Ce4">
+                                <items/>
+                            </toolbar>
+                        </subviews>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstItem="BUV-FR-Ce4" firstAttribute="leading" secondItem="GVK-7L-Fs8" secondAttribute="leading" id="B5b-ZL-aXy"/>
+                            <constraint firstItem="BUV-FR-Ce4" firstAttribute="top" secondItem="7ZZ-Yj-QTv" secondAttribute="bottom" id="FGC-7L-Qgg"/>
+                            <constraint firstAttribute="trailing" secondItem="BUV-FR-Ce4" secondAttribute="trailing" id="Hws-q3-9x4"/>
+                            <constraint firstAttribute="trailing" secondItem="7ZZ-Yj-QTv" secondAttribute="trailing" id="S53-X3-aSi"/>
+                            <constraint firstItem="7ZZ-Yj-QTv" firstAttribute="leading" secondItem="GVK-7L-Fs8" secondAttribute="leading" id="aQa-NV-7qY"/>
+                            <constraint firstItem="Zws-CJ-rtL" firstAttribute="top" secondItem="BUV-FR-Ce4" secondAttribute="bottom" id="ey9-xA-ip6"/>
+                            <constraint firstItem="7ZZ-Yj-QTv" firstAttribute="top" secondItem="GVK-7L-Fs8" secondAttribute="top" id="gkS-DG-IQX"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="collectionView" destination="7ZZ-Yj-QTv" id="Pes-iP-Wnb"/>
+                        <outlet property="toolBar" destination="BUV-FR-Ce4" id="dnj-BG-nMR"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="3HS-bz-Pof" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="1773.5999999999999" y="546.47676161919048"/>
+        </scene>
+    </scenes>
+    <resources>
+        <image name="hg_image_not_selected" width="30" height="30"/>
+    </resources>
+</document>

+ 6 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImage.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

BIN
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImage.xcassets/hg_image_not_selected.imageset/CellGreySelected@2x.png


+ 21 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImage.xcassets/hg_image_not_selected.imageset/Contents.json

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

BIN
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImage.xcassets/hg_image_selected.imageset/CellBlueSelected@2x.png


+ 21 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImage.xcassets/hg_image_selected.imageset/Contents.json

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

+ 51 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImageCollectionViewCell.swift

@@ -0,0 +1,51 @@
+//
+//  HGImageCollectionViewCell.swift
+//  hangge_1512
+//
+//  Created by hangge on 2017/1/7.
+//  Copyright © 2017年 hangge.com. All rights reserved.
+//
+
+import UIKit
+
+//图片缩略图集合页单元格
+open class HGImageCollectionViewCell: UICollectionViewCell {
+    //显示缩略图
+    @IBOutlet weak var imageView:UIImageView!
+    
+    //显示选中状态的图标
+    @IBOutlet weak var selectedIcon:UIImageView!
+    
+    //设置是否选中
+    open override var isSelected: Bool {
+        didSet{
+            if isSelected {
+                selectedIcon.image = UIImage(named: "hg_image_selected")
+            }else{
+                selectedIcon.image = UIImage(named: "hg_image_not_selected")
+            }
+        }
+    }
+    
+    //播放动画,是否选中的图标改变时使用
+    func playAnimate() {
+        //图标先缩小,再放大
+        UIView.animateKeyframes(withDuration: 0.4, delay: 0, options: .allowUserInteraction,
+                                animations: {
+            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.2,
+                               animations: {
+                self.selectedIcon.transform = CGAffineTransform(scaleX: 0.7, y: 0.7)
+            })
+            UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.4,
+                               animations: {
+                self.selectedIcon.transform = CGAffineTransform.identity
+            })
+            }, completion: nil)
+    }
+    
+    open override func awakeFromNib() {
+        super.awakeFromNib()
+        imageView.contentMode = .scaleAspectFill
+        imageView.clipsToBounds = true
+    }
+}

+ 190 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImageCollectionViewController.swift

@@ -0,0 +1,190 @@
+//
+//  HGImageCollectionViewController.swift
+//  hangge_1512
+//
+//  Created by hangge on 2017/1/7.
+//  Copyright © 2017年 hangge.com. All rights reserved.
+//
+
+import UIKit
+import Photos
+
+//图片缩略图集合页控制器
+class HGImageCollectionViewController: UIViewController {
+    //用于显示所有图片缩略图的collectionView
+    @IBOutlet weak var collectionView:UICollectionView!
+    
+    //下方工具栏
+    @IBOutlet weak var toolBar:UIToolbar!
+
+    //取得的资源结果,用了存放的PHAsset
+    var assetsFetchResults:PHFetchResult<PHAsset>?
+    
+    //带缓存的图片管理对象
+    var imageManager:PHCachingImageManager!
+    
+    //缩略图大小
+    var assetGridThumbnailSize:CGSize!
+    
+    //每次最多可选择的照片数量
+    var maxSelected:Int = Int.max
+    
+    //照片选择完毕后的回调
+    var completeHandler:((_ assets:[PHAsset])->())?
+    
+    //完成按钮
+    var completeButton:HGImageCompleteButton!
+    
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+        
+        //根据单元格的尺寸计算我们需要的缩略图大小
+        let scale = UIScreen.main.scale
+        let cellSize = (self.collectionView.collectionViewLayout as!
+            UICollectionViewFlowLayout).itemSize
+        assetGridThumbnailSize = CGSize(width: cellSize.width*scale ,
+                                        height: cellSize.height*scale)
+    }
+
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        //背景色设置为白色(默认是黑色)
+        self.collectionView.backgroundColor = UIColor.white
+        
+        //初始化和重置缓存
+        self.imageManager = PHCachingImageManager()
+        self.resetCachedAssets()
+        
+        //设置单元格尺寸
+        let layout = (self.collectionView.collectionViewLayout as!
+            UICollectionViewFlowLayout)
+        layout.itemSize = CGSize(width: UIScreen.main.bounds.size.width/4-1,
+                                 height: UIScreen.main.bounds.size.width/4-1)
+        //允许多选
+        self.collectionView.allowsMultipleSelection = true
+        
+        //添加导航栏右侧的取消按钮
+        let rightBarItem = UIBarButtonItem(title: "取消", style: .plain,
+                                           target: self, action: #selector(cancel))
+        self.navigationItem.rightBarButtonItem = rightBarItem
+      
+        //添加下方工具栏的完成按钮
+        completeButton = HGImageCompleteButton()
+        completeButton.addTarget(target: self, action: #selector(finishSelect))
+        completeButton.center = CGPoint(x: UIScreen.main.bounds.width - 50, y: 22)
+        completeButton.isEnabled = false
+        toolBar.addSubview(completeButton)
+    }
+
+    //重置缓存
+    func resetCachedAssets(){
+        self.imageManager.stopCachingImagesForAllAssets()
+    }
+    
+    
+    //取消按钮点击
+    @objc func cancel() {
+        //退出当前视图控制器
+        self.navigationController?.dismiss(animated: true, completion: nil)
+    }
+    
+    //获取已选择个数
+    func selectedCount() -> Int {
+        return self.collectionView.indexPathsForSelectedItems?.count ?? 0
+    }
+
+    //完成按钮点击
+    @objc func finishSelect(){
+        //取出已选择的图片资源
+        var assets:[PHAsset] = []
+        if let indexPaths = self.collectionView.indexPathsForSelectedItems{
+            for indexPath in indexPaths{
+                assets.append(assetsFetchResults![indexPath.row] )
+            }
+        }
+        //调用回调函数
+        self.navigationController?.dismiss(animated: true, completion: {
+            self.completeHandler?(assets)
+        })
+    }
+}
+
+//图片缩略图集合页控制器UICollectionViewDataSource,UICollectionViewDelegate协议方法的实现
+extension HGImageCollectionViewController:UICollectionViewDataSource
+,UICollectionViewDelegate{
+    //CollectionView项目
+    func collectionView(_ collectionView: UICollectionView,
+                        numberOfItemsInSection section: Int) -> Int {
+        return self.assetsFetchResults?.count ?? 0
+    }
+    
+    // 获取单元格
+    func collectionView(_ collectionView: UICollectionView,
+                        cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        //获取storyboard里设计的单元格,不需要再动态添加界面元素
+        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",
+                                    for: indexPath) as! HGImageCollectionViewCell
+        let asset = self.assetsFetchResults![indexPath.row]
+        //获取缩略图
+        self.imageManager.requestImage(for: asset, targetSize: assetGridThumbnailSize,
+                                       contentMode: .aspectFill, options: nil) {
+                                        (image, nfo) in
+            cell.imageView.image = image
+        }
+        
+        return cell
+    }
+    
+    //单元格选中响应
+    func collectionView(_ collectionView: UICollectionView,
+                        didSelectItemAt indexPath: IndexPath) {
+        if let cell = collectionView.cellForItem(at: indexPath)
+            as? HGImageCollectionViewCell{
+            //获取选中的数量
+            let count = self.selectedCount()
+            //如果选择的个数大于最大选择数
+            if count > self.maxSelected {
+                //设置为不选中状态
+                collectionView.deselectItem(at: indexPath, animated: false)
+                //弹出提示
+                let title = "当前最多可选择\(self.maxSelected)张照片"
+                let alertController = UIAlertController(title: title, message: nil,
+                                                        preferredStyle: .alert)
+                
+                let cancelAction = UIAlertAction(title:"我知道了", style: .cancel,
+                                                 handler:nil)
+                alertController.addAction(cancelAction)
+                self.present(alertController, animated: true, completion: nil)
+            }
+            //如果不超过最大选择数
+            else{
+                //改变完成按钮数字,并播放动画
+                completeButton.num = count
+                if count > 0 && !self.completeButton.isEnabled{
+                    completeButton.isEnabled = true
+                }
+                cell.playAnimate()
+            }
+        }
+    }
+    
+    //单元格取消选中响应
+    func collectionView(_ collectionView: UICollectionView,
+                        didDeselectItemAt indexPath: IndexPath) {
+        if let cell = collectionView.cellForItem(at: indexPath)
+            as? HGImageCollectionViewCell{
+             //获取选中的数量
+            let count = self.selectedCount()
+            completeButton.num = count
+             //改变完成按钮数字,并播放动画
+            if count == 0{
+                completeButton.isEnabled = false
+            }
+            cell.playAnimate()
+        }
+    }
+}
+
+
+

+ 101 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImageCompleteButton.swift

@@ -0,0 +1,101 @@
+//
+//  HGImageCompleteButton.swift
+//  hangge_1512
+//
+//  Created by hangge on 2017/1/7.
+//  Copyright © 2017年 hangge.com. All rights reserved.
+//
+
+import UIKit
+
+//照片选择页下方工具栏的“完成”按钮
+class HGImageCompleteButton: UIView {
+    //已选照片数量标签
+    var numLabel:UILabel!
+    //按钮标题标签“完成”
+    var titleLabel:UILabel!
+    
+    //按钮的默认尺寸
+    let defaultFrame = CGRect(x:0, y:0, width:70, height:20)
+    
+    //文字颜色(同时也是数字背景颜色)
+    let titleColor = UIColor(red: 0x09/255, green: 0xbb/255, blue: 0x07/255, alpha: 1)
+    
+    //点击点击手势
+    var tapSingle:UITapGestureRecognizer?
+    
+    //设置数量
+    var num:Int = 0{
+        didSet{
+            if num == 0{
+                numLabel.isHidden = true
+            }else{
+                numLabel.isHidden = false
+                numLabel.text = "\(num)"
+                playAnimate()
+            }
+        }
+    }
+    
+    //是否可用
+    var isEnabled:Bool = true {
+        didSet{
+            if isEnabled {
+                titleLabel.textColor = titleColor
+                tapSingle?.isEnabled = true
+            }else{
+                titleLabel.textColor = UIColor.gray
+                tapSingle?.isEnabled = false
+            }
+        }
+    }
+    
+    init(){
+        super.init(frame:defaultFrame)
+    
+        //已选照片数量标签初始化
+        numLabel = UILabel(frame:CGRect(x: 0 , y: 0 , width: 20, height: 20))
+        numLabel.backgroundColor = titleColor
+        numLabel.layer.cornerRadius = 10
+        numLabel.layer.masksToBounds = true
+        numLabel.textAlignment = .center
+        numLabel.font = UIFont.systemFont(ofSize: 15)
+        numLabel.textColor = UIColor.white
+        numLabel.isHidden = true
+        self.addSubview(numLabel)
+        
+        //按钮标题标签初始化
+        titleLabel = UILabel(frame:CGRect(x: 20 , y: 0 ,
+                                          width: defaultFrame.width - 20,
+                                          height: 20))
+        titleLabel.text = "完成"
+        titleLabel.textAlignment = .center
+        titleLabel.font = UIFont.systemFont(ofSize: 15)
+        titleLabel.textColor = titleColor
+        self.addSubview(titleLabel)
+    }
+    
+    required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+    }
+    
+    //用户数字改变时播放的动画
+    func playAnimate() {
+        //从小变大,且有弹性效果
+        self.numLabel.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
+        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5,
+                       initialSpringVelocity: 0.5, options: UIView.AnimationOptions(),
+                       animations: {
+            self.numLabel.transform = CGAffineTransform.identity
+        }, completion: nil)
+    }
+    
+    //添加事件响应
+    func addTarget(target: Any?, action: Selector?) {
+        //单击监听
+        tapSingle = UITapGestureRecognizer(target:target,action:action)
+        tapSingle!.numberOfTapsRequired = 1
+        tapSingle!.numberOfTouchesRequired = 1
+        self.addGestureRecognizer(tapSingle!)
+    }
+}

+ 26 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImagePickerCell.swift

@@ -0,0 +1,26 @@
+//
+//  HGImagePickerCell.swift
+//  hangge_1512
+//
+//  Created by hangge on 2017/1/7.
+//  Copyright © 2017年 hangge.com. All rights reserved.
+//
+
+import UIKit
+
+//相簿列表单元格
+class HGImagePickerCell: UITableViewCell {
+    //相簿名称标签
+    @IBOutlet weak var titleLabel:UILabel!
+    //照片数量标签
+    @IBOutlet weak var countLabel:UILabel!
+    
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        self.layoutMargins = UIEdgeInsets.zero
+    }
+
+    override func setSelected(_ selected: Bool, animated: Bool) {
+        super.setSelected(selected, animated: animated)
+    }
+}

+ 220 - 0
RainbowPlanet/RainbowPlanet/Tools/HGImagePicker/HGImagePickerController.swift

@@ -0,0 +1,220 @@
+//
+//  HGImageAlbumItem.swift
+//  hangge_1512
+//
+//  Created by hangge on 2017/1/7.
+//  Copyright © 2017年 hangge.com. All rights reserved.
+//
+
+import UIKit
+import Photos
+
+//相簿列表项
+struct HGImageAlbumItem {
+    //相簿名称
+    var title:String?
+    //相簿内的资源
+    var fetchResult:PHFetchResult<PHAsset>
+}
+
+//相簿列表页控制器
+class HGImagePickerController: UIViewController {
+    //显示相簿列表项的表格
+    @IBOutlet weak var tableView:UITableView!
+    
+    //相簿列表项集合
+    var items:[HGImageAlbumItem] = []
+    
+    //每次最多可选择的照片数量
+    var maxSelected:Int = Int.max
+    
+    //照片选择完毕后的回调
+    var completeHandler:((_ assets:[PHAsset])->())?
+    
+    //从xib或者storyboard加载完毕就会调用
+    override func awakeFromNib() {
+        super.awakeFromNib()
+        
+        //申请权限
+        PHPhotoLibrary.requestAuthorization({ (status) in
+            if status != .authorized {
+                return
+            }
+            
+            // 列出所有系统的智能相册
+            let smartOptions = PHFetchOptions()
+            let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum,
+                                                              subtype: .albumRegular,
+                                                              options: smartOptions)
+            self.convertCollection(collection: smartAlbums)
+            
+            //列出所有用户创建的相册
+            let userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil)
+            self.convertCollection(collection: userCollections
+                as! PHFetchResult<PHAssetCollection>)
+            
+            //相册按包含的照片数量排序(降序)
+            self.items.sort { (item1, item2) -> Bool in
+                return item1.fetchResult.count > item2.fetchResult.count
+            }
+            
+            //异步加载表格数据,需要在主线程中调用reloadData() 方法
+            DispatchQueue.main.async{
+                self.tableView?.reloadData()
+                
+                //首次进来后直接进入第一个相册图片展示页面(相机胶卷)
+                if let imageCollectionVC = self.storyboard?
+                    .instantiateViewController(withIdentifier: "hgImageCollectionVC")
+                    as? HGImageCollectionViewController{
+                    imageCollectionVC.title = self.items.first?.title
+                    imageCollectionVC.assetsFetchResults = self.items.first?.fetchResult
+                    imageCollectionVC.completeHandler = self.completeHandler
+                    imageCollectionVC.maxSelected = self.maxSelected
+                    self.navigationController?.pushViewController(imageCollectionVC,
+                                                                  animated: false)
+                }
+            }
+        })
+    }
+    
+    //页面加载完毕
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        
+        //设置标题
+        title = "相簿"
+        //设置表格相关样式属性
+        self.tableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
+        self.tableView.rowHeight = 55
+        //添加导航栏右侧的取消按钮
+        let rightBarItem = UIBarButtonItem(title: "取消", style: .plain, target: self,
+                                           action:#selector(cancel) )
+        self.navigationItem.rightBarButtonItem = rightBarItem
+    }
+    
+    //转化处理获取到的相簿
+    private func convertCollection(collection:PHFetchResult<PHAssetCollection>){
+        for i in 0..<collection.count{
+            //获取出但前相簿内的图片
+            let resultsOptions = PHFetchOptions()
+            resultsOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",
+                                                               ascending: false)]
+            resultsOptions.predicate = NSPredicate(format: "mediaType = %d",
+                                                   PHAssetMediaType.image.rawValue)
+            let c = collection[i]
+            let assetsFetchResult = PHAsset.fetchAssets(in: c , options: resultsOptions)
+            //没有图片的空相簿不显示
+            if assetsFetchResult.count > 0 {
+                let title = titleOfAlbumForChinse(title: c.localizedTitle)
+                items.append(HGImageAlbumItem(title: title,
+                                              fetchResult: assetsFetchResult))
+            }
+        }
+    }
+    
+    //由于系统返回的相册集名称为英文,我们需要转换为中文
+    private func titleOfAlbumForChinse(title:String?) -> String? {
+        if title == "Slo-mo" {
+            return "慢动作"
+        } else if title == "Recently Added" {
+            return "最近添加"
+        } else if title == "Favorites" {
+            return "个人收藏"
+        } else if title == "Recently Deleted" {
+            return "最近删除"
+        } else if title == "Videos" {
+            return "视频"
+        } else if title == "All Photos" {
+            return "所有照片"
+        } else if title == "Selfies" {
+            return "自拍"
+        } else if title == "Screenshots" {
+            return "屏幕快照"
+        } else if title == "Camera Roll" {
+            return "相机胶卷"
+        }
+        return title
+    }
+    
+    //取消按钮点击
+    @objc func cancel() {
+        //退出当前视图控制器
+        self.dismiss(animated: true, completion: nil)
+    }
+    
+    //页面跳转
+    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
+        //如果是跳转到展示相簿缩略图页面
+        if segue.identifier == "showImages"{
+            //获取照片展示控制器
+            guard let imageCollectionVC = segue.destination
+                as? HGImageCollectionViewController,
+                let cell = sender as? HGImagePickerCell else{
+                return
+            }
+            //设置回调函数
+            imageCollectionVC.completeHandler = completeHandler
+            //设置标题
+            imageCollectionVC.title = cell.titleLabel.text
+            //设置最多可选图片数量
+            imageCollectionVC.maxSelected = self.maxSelected
+            guard  let indexPath = self.tableView.indexPath(for: cell) else { return }
+            
+            //获取选中的相簿信息
+            let fetchResult = self.items[indexPath.row].fetchResult
+            //传递相簿内的图片资源
+            imageCollectionVC.assetsFetchResults = fetchResult
+        }
+    }
+    
+    override func didReceiveMemoryWarning() {
+        super.didReceiveMemoryWarning()
+    }
+}
+
+//相簿列表页控制器UITableViewDelegate,UITableViewDataSource协议方法的实现
+extension HGImagePickerController:UITableViewDelegate,UITableViewDataSource{
+    //设置单元格内容
+    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
+        -> UITableViewCell {
+        //同一形式的单元格重复使用,在声明时已注册
+        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
+            as! HGImagePickerCell
+        let item = self.items[indexPath.row]
+        cell.titleLabel.text = "\(item.title ?? "") "
+        cell.countLabel.text = "(\(item.fetchResult.count))"
+        return cell
+    }
+    
+    //表格单元格数量
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return self.items.count
+    }
+    
+    //表格单元格选中
+    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        tableView.deselectRow(at: indexPath, animated: true)
+    }
+}
+
+extension UIViewController {
+    //HGImagePicker提供给外部调用的接口,同于显示图片选择页面
+    func presentHGImagePicker(maxSelected:Int = Int.max,
+                              completeHandler:((_ assets:[PHAsset])->())?)
+        -> HGImagePickerController?{
+        //获取图片选择视图控制器
+        if let vc = UIStoryboard(name: "HGImage", bundle: Bundle.main)
+            .instantiateViewController(withIdentifier: "imagePickerVC")
+            as? HGImagePickerController{
+            //设置选择完毕后的回调
+            vc.completeHandler = completeHandler
+            //设置图片最多选择的数量
+            vc.maxSelected = maxSelected
+            //将图片选择视图控制器外添加个导航控制器,并显示
+            let nav = UINavigationController(rootViewController: vc)
+            self.present(nav, animated: true, completion: nil)
+            return vc
+        }
+        return nil
+    }
+}