├── XYPhoto ├── sv-SE.lproj │ ├── Main.strings │ └── LaunchScreen.strings ├── zh-Hans.lproj │ ├── Main.strings │ └── LaunchScreen.strings ├── Assets.xcassets │ ├── Contents.json │ ├── backIcon.imageset │ │ ├── backIcon@2x.png │ │ ├── backIcon@3x.png │ │ └── Contents.json │ ├── thumbs_default.imageset │ │ ├── thumbs_default@2x.png │ │ └── Contents.json │ ├── fliter_normal_tribe_.imageset │ │ ├── fliter_normal_tribe_@2x.png │ │ └── Contents.json │ ├── fliter_selected_tribe_.imageset │ │ ├── fliter_selected_tribe_@2x.png │ │ ├── fliter_selected_tribe_@3x.png │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── Model │ └── PhotoGroupItem.swift ├── CustomSettings │ └── CustomSetting.plist ├── Controller │ ├── NavgationViewController.swift │ └── PhotoLibaryViewController.swift ├── Tool │ └── PhotoLibraryManager.swift ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── Module │ └── PhotoLibaryCollectionView.swift ├── PhotoGroupPickerViewController.swift ├── AppDelegate.swift ├── ViewController.swift ├── View │ └── PhotoLibraryCollectionCell.swift ├── PhotoGroupCell.swift └── PhotoGroupTableView.swift ├── XYPhoto.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── jiaxiaoyan.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcuserdata │ └── jiaxiaoyan.xcuserdatad │ │ ├── xcschemes │ │ ├── xcschememanagement.plist │ │ └── XYPhoto.xcscheme │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist └── project.pbxproj ├── README.md ├── XYPhotoTests ├── Info.plist └── XYPhotoTests.swift ├── XYPhotoUITests ├── Info.plist └── XYPhotoUITests.swift └── Untitled Diagram.xml /XYPhoto/sv-SE.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /XYPhoto/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /XYPhoto/sv-SE.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /XYPhoto/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/backIcon.imageset/backIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloWorldJXY/XYPhoto/HEAD/XYPhoto/Assets.xcassets/backIcon.imageset/backIcon@2x.png -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/backIcon.imageset/backIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloWorldJXY/XYPhoto/HEAD/XYPhoto/Assets.xcassets/backIcon.imageset/backIcon@3x.png -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/thumbs_default.imageset/thumbs_default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloWorldJXY/XYPhoto/HEAD/XYPhoto/Assets.xcassets/thumbs_default.imageset/thumbs_default@2x.png -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/fliter_normal_tribe_.imageset/fliter_normal_tribe_@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloWorldJXY/XYPhoto/HEAD/XYPhoto/Assets.xcassets/fliter_normal_tribe_.imageset/fliter_normal_tribe_@2x.png -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/fliter_selected_tribe_.imageset/fliter_selected_tribe_@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloWorldJXY/XYPhoto/HEAD/XYPhoto/Assets.xcassets/fliter_selected_tribe_.imageset/fliter_selected_tribe_@2x.png -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/fliter_selected_tribe_.imageset/fliter_selected_tribe_@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloWorldJXY/XYPhoto/HEAD/XYPhoto/Assets.xcassets/fliter_selected_tribe_.imageset/fliter_selected_tribe_@3x.png -------------------------------------------------------------------------------- /XYPhoto.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /XYPhoto.xcodeproj/project.xcworkspace/xcuserdata/jiaxiaoyan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HelloWorldJXY/XYPhoto/HEAD/XYPhoto.xcodeproj/project.xcworkspace/xcuserdata/jiaxiaoyan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XYPhoto 2 | init func 3 | 4 | PhotoLibraryManager().show(viewcontroller : UIViewcontroller) 5 | 6 | effection 7 | 8 | it seemed like WeiXin photo selection style ,however it used Photos Framework to replace ALasset Framework 9 | -------------------------------------------------------------------------------- /XYPhoto/Model/PhotoGroupItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoGroupItem.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | 12 | class PhotoGroupItem: NSObject { 13 | 14 | var groupName : String! 15 | var assetCounts : NSInteger = 0 16 | 17 | var group : PHAssetCollection! 18 | 19 | } 20 | -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/thumbs_default.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "thumbs_default@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/fliter_normal_tribe_.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "fliter_normal_tribe_@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /XYPhoto/CustomSettings/CustomSetting.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | albums 6 | 7 | defaultStyle 8 | 9 | styleOne 10 | 11 | styleTwo 12 | 13 | styleThree 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/backIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "backIcon@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "backIcon@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/fliter_selected_tribe_.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "fliter_selected_tribe_@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "fliter_selected_tribe_@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /XYPhotoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /XYPhotoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /XYPhoto.xcodeproj/xcuserdata/jiaxiaoyan.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | XYPhoto.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | E1068AD71D3F2DC1008A90F9 16 | 17 | primary 18 | 19 | 20 | E1068AEB1D3F2DC1008A90F9 21 | 22 | primary 23 | 24 | 25 | E1068AF61D3F2DC1008A90F9 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /XYPhoto/Controller/NavgationViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NavgationViewController.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class NavgationViewController: UINavigationController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 30 | // Get the new view controller using segue.destinationViewController. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /XYPhoto/Tool/PhotoLibraryManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoLibraryManager.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/26. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PhotoLibraryManager { 12 | 13 | internal func show(_ viewcontroller : UIViewController) { 14 | // let pickerVC = PhotoLibaryViewController() 15 | // let photoGroupVC = PhotoGroupPickerViewController() 16 | // let nav = UINavigationController.init(rootViewController: photoGroupVC) 17 | // nav.pushViewController(pickerVC, animated: false) 18 | // nav.navigationBar.barStyle = .black 19 | // viewcontroller.present(nav, animated: true,completion: nil) 20 | let pickerVC = PhotoLibaryViewController() 21 | let photoGroupVC = PhotoGroupPickerViewController() 22 | let nav = UINavigationController.init(rootViewController: photoGroupVC) 23 | nav.pushViewController(pickerVC, animated: false) 24 | nav.navigationBar.barStyle = .black 25 | viewcontroller.present(nav, animated: true,completion: nil) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /XYPhotoTests/XYPhotoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XYPhotoTests.swift 3 | // XYPhotoTests 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import XYPhoto 11 | 12 | class XYPhotoTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /XYPhotoUITests/XYPhotoUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XYPhotoUITests.swift 3 | // XYPhotoUITests 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class XYPhotoUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /XYPhoto.xcodeproj/xcuserdata/jiaxiaoyan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /XYPhoto/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /XYPhoto/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | 相册 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSPhotoLibraryUsageDescription 28 | XXXX想获取您的相册权限 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /XYPhoto/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /XYPhoto/Module/PhotoLibaryCollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoLibaryCollectionView.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | 12 | class PhotoLibaryCollectionView: UICollectionView ,UICollectionViewDataSource,UICollectionViewDelegate{ 13 | 14 | var cellIdentifier = "PhotoLibraryCollectionCell" 15 | var assetCollection : PHAssetCollection? 16 | 17 | var assetArray = [PHAsset]() 18 | 19 | func setUpAssetCollection( _ assetCollection : PHAssetCollection) { 20 | backgroundColor = UIColor.white 21 | delegate = self 22 | dataSource = self 23 | 24 | self.register(PhotoLibraryCollectionCell.self, forCellWithReuseIdentifier: cellIdentifier) 25 | weak var weakSelf = self 26 | 27 | let fetchResult = PHAsset.fetchAssets(in: assetCollection, options: nil) 28 | fetchResult.enumerateObjects({ (asset, count, success) in 29 | weakSelf!.assetArray.append(asset ) 30 | }) 31 | } 32 | 33 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 34 | 35 | } 36 | 37 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{ 38 | return assetArray.count 39 | } 40 | 41 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{ 42 | let cell = dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! PhotoLibraryCollectionCell 43 | let phasset = assetArray[indexPath.row] 44 | cell.fillData(phasset) 45 | return cell 46 | } 47 | 48 | func numberOfSections(in collectionView: UICollectionView) -> Int{ 49 | return 1 50 | } 51 | 52 | func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool{ 53 | return false 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /XYPhoto/PhotoGroupPickerViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoGroupPickerViewController.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | import UIKit 9 | import Photos 10 | 11 | class PhotoGroupPickerViewController: UIViewController,PhotoGroupTableDelegate { 12 | var tableView : PhotoGroupTableView! 13 | 14 | override func viewDidLoad() { 15 | view.backgroundColor = UIColor.white 16 | 17 | setUpTableView() 18 | } 19 | 20 | func setUpTableView(){ 21 | if tableView == nil{ 22 | tableView = PhotoGroupTableView() 23 | let rect = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) 24 | tableView.setUpSelf(rect) 25 | tableView.photoGroupDelegate = self 26 | view.addSubview(tableView) 27 | } 28 | } 29 | 30 | override func viewWillAppear(_ animated: Bool) { 31 | super.viewWillAppear(animated) 32 | setnav() 33 | } 34 | func setnav() { 35 | title = "相册" 36 | let backButton = UIButton(type: .custom) 37 | backButton.frame = CGRect(x: 0, y: 0, width: 110, height: 44) 38 | backButton.backgroundColor = UIColor.clear 39 | backButton.setTitle("取消", for: UIControlState()) 40 | backButton.titleEdgeInsets = UIEdgeInsetsMake(0, 40, 0, -40) 41 | backButton.setTitleColor(UIColor.white, for: UIControlState()) 42 | backButton.addTarget(self, action: #selector(PhotoLibaryViewController.cancleButtonClick), for: .touchUpInside) 43 | self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: backButton) 44 | self.navigationItem.hidesBackButton = true 45 | } 46 | 47 | func cancleButtonClick() { 48 | 49 | self.dismiss(animated: true, completion: nil) 50 | 51 | } 52 | func didSelectPhotoGroupTableRowCallBack(_ assetCollection : PHAssetCollection){ 53 | let vc = PhotoLibaryViewController() 54 | self.navigationController?.pushViewController(vc, animated: true) 55 | 56 | vc.navTitle = assetCollection.localizedTitle! 57 | vc.assetCollection = assetCollection 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /XYPhoto/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /XYPhoto/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | let button:UIButton = UIButton() 17 | //设置frame 18 | let frame = CGRect(x: 100, y: 60, width: 100, height: 60) 19 | button.frame = frame 20 | //设置字体颜色 21 | button.setTitleColor(UIColor.red, for: UIControlState()) 22 | //设置字体 23 | button.setTitle("点我有惊喜", for: UIControlState()) 24 | //添加方法 25 | button.addTarget(self, action: #selector(ViewController.buttonClick), for: UIControlEvents.touchUpInside) 26 | //添加到父控件 27 | self.view.addSubview(button) 28 | 29 | } 30 | 31 | func buttonClick(){ 32 | let status = PHPhotoLibrary.authorizationStatus() 33 | 34 | switch status { 35 | case .authorized: 36 | PhotoLibraryManager().show(self) 37 | break 38 | case .notDetermined: 39 | PHPhotoLibrary.requestAuthorization({ (status) in }) 40 | break 41 | case .denied: 42 | fetchAlbumAuthoration() 43 | break 44 | default: 45 | fetchAlbumAuthoration() 46 | } 47 | } 48 | 49 | func fetchAlbumAuthoration(){ 50 | let alertController = UIAlertController(title: "此应用无权限访问相册", message: "您可以到设置-隐私-照片,打开访问权限", preferredStyle: .alert) 51 | let settingAction = UIAlertAction(title: "去设置", style: .default) { (alertAction) in 52 | let settingUrl = URL(string: UIApplicationOpenSettingsURLString) 53 | UIApplication.shared.openURL(settingUrl!) 54 | } 55 | let cancleAction = UIAlertAction(title: "取消", style: .cancel, handler: nil) 56 | alertController.addAction(cancleAction) 57 | alertController.addAction(settingAction) 58 | self.present(alertController, animated: true, completion: nil) 59 | } 60 | deinit { 61 | print("viewcontroller deinit") 62 | } 63 | override func didReceiveMemoryWarning() { 64 | super.didReceiveMemoryWarning() 65 | // Dispose of any resources that can be recreated. 66 | } 67 | 68 | 69 | } 70 | 71 | -------------------------------------------------------------------------------- /XYPhoto/View/PhotoLibraryCollectionCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoLibraryCollectionCell.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | class PhotoLibraryCollectionCell: UICollectionViewCell { 12 | 13 | var imageView: UIImageView! 14 | var selectButton: UIButton! 15 | 16 | var selectState = false 17 | 18 | override init(frame: CGRect) { 19 | super.init(frame: frame) 20 | self.imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.bounds.size.width, height: self.bounds.size.height)) 21 | // self.imageView.contentMode = .scaleToFill 22 | // self.imageView.clipsToBounds = true 23 | 24 | self.selectButton = UIButton(type: .custom) 25 | self.selectButton.setImage(UIImage(named: "fliter_normal_tribe_"), for: .normal) 26 | self.selectButton.frame = CGRect(x: self.bounds.size.width - 25, y: 5, width: 20, height: 20) 27 | self.selectButton.addTarget(self, action: #selector(PhotoLibraryCollectionCell.selectButtonClick(_:)), for: .touchUpInside) 28 | 29 | self.contentView.addSubview(self.imageView) 30 | self.contentView.addSubview(self.selectButton) 31 | } 32 | 33 | required init?(coder aDecoder: NSCoder) { 34 | fatalError("init(coder:) has not been implemented") 35 | } 36 | func selectButtonClick(_ sender: AnyObject) { 37 | selectState = !selectState 38 | setButton() 39 | } 40 | override func awakeFromNib() { 41 | super.awakeFromNib() 42 | // Initialization code 43 | } 44 | 45 | func setOriginStatus() { 46 | imageView.isHidden = true 47 | selectButton.isHidden = true 48 | } 49 | 50 | func setButton() { 51 | if selectState { 52 | selectButton.setImage(UIImage(named: "fliter_selected_tribe_"), for: UIControlState()) 53 | }else{ 54 | selectButton.setImage(UIImage(named: "fliter_normal_tribe_"), for: UIControlState()) 55 | } 56 | } 57 | func fillData(_ phAsset : PHAsset) { 58 | // setButton() 59 | // backgroundColor = UIColor.white 60 | let option = PHImageRequestOptions() 61 | option.deliveryMode = .opportunistic 62 | option.isSynchronous = true 63 | PHCachingImageManager().requestImage(for: phAsset, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: option, resultHandler: { (image, objects) in//获取相册的缩略图 64 | self.imageView.image = image! 65 | 66 | }) 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /XYPhoto/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /XYPhoto/PhotoGroupCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoGroupCell.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | class PhotoGroupCell: UITableViewCell { 12 | var nameFont = CGFloat(16) 13 | let cellHeight = 60 14 | var group : PHAssetCollection! 15 | 16 | var thumbImgView: UIImageView! 17 | var groupNameLabel: UILabel! 18 | var groupCountslabel: UILabel! 19 | 20 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 21 | super.init(style: style, reuseIdentifier: reuseIdentifier) 22 | self.thumbImgView = UIImageView(frame: CGRect(x: 0, y: 0, width: cellHeight, height: cellHeight)) 23 | self.thumbImgView.clipsToBounds = true 24 | self.thumbImgView.image = UIImage(named: "thumbs_default") 25 | 26 | self.groupNameLabel = UILabel() 27 | self.groupNameLabel.frame = CGRect(x: Int(thumbImgView.frame.maxX + 15), y: 0, width: 50, height: cellHeight) 28 | self.groupNameLabel.font = UIFont.systemFont(ofSize: nameFont) 29 | self.groupNameLabel.textColor = UIColor.gray 30 | 31 | self.groupCountslabel = UILabel() 32 | self.groupCountslabel.frame = CGRect(x: Int(groupNameLabel.frame.maxX + 15), y: 0, width: 50, height: cellHeight) 33 | self.groupCountslabel.font = UIFont.systemFont(ofSize: 15) 34 | self.groupCountslabel.textColor = UIColor.lightGray 35 | 36 | self.addSubview(self.thumbImgView) 37 | self.addSubview(self.groupNameLabel) 38 | self.addSubview(self.groupCountslabel) 39 | } 40 | 41 | required init?(coder aDecoder: NSCoder) { 42 | fatalError("init(coder:) has not been implemented") 43 | } 44 | override func awakeFromNib() { 45 | super.awakeFromNib() 46 | // Initialization code 47 | } 48 | 49 | override func setSelected(_ selected: Bool, animated: Bool) { 50 | super.setSelected(selected, animated: animated) 51 | 52 | // Configure the view for the selected state 53 | } 54 | 55 | public func reloadCellWithPHAssetCollection(assetCollection : PHAssetCollection) { 56 | 57 | selectionStyle = .none 58 | let fetchResult = PHAsset.fetchAssets(in: assetCollection , options: nil) 59 | let name = assetCollection.localizedTitle! as NSString 60 | let maxSize = CGSize(width: 320, height: 100) 61 | let nameAttributes = [NSFontAttributeName:UIFont.systemFont(ofSize: nameFont)] 62 | 63 | self.groupNameLabel.text = name as String 64 | let nameRect : CGRect = name.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: nameAttributes, context: nil) 65 | self.groupNameLabel.frame = CGRect(x: Int(thumbImgView.frame.maxX + 15), y: 0, width: Int(nameRect.size.width + 10), height: cellHeight) 66 | 67 | let countString = NSString(string: "( " + String(fetchResult.count) + " )") 68 | let attributes = [NSFontAttributeName:UIFont.systemFont(ofSize: nameFont)] 69 | let rect:CGRect = countString.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: attributes, context: nil) 70 | 71 | self.groupCountslabel.text = countString as String 72 | self.groupCountslabel.frame = CGRect(x: Int(groupNameLabel.frame.maxX + 15), y: 0, width: Int(rect.size.width + 10), height: cellHeight) 73 | 74 | if let lastCollection = fetchResult.lastObject { 75 | let option = PHImageRequestOptions() 76 | option.deliveryMode = .opportunistic 77 | option.isSynchronous = true 78 | 79 | PHImageManager.default().requestImage(for: lastCollection, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFill, options: option) { (thumbImg, objects) in 80 | DispatchQueue.main.async { 81 | self.thumbImgView.image = thumbImg 82 | } 83 | } 84 | } 85 | 86 | } 87 | deinit { 88 | //print("PhotoGroupCell deinit") 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /XYPhoto/PhotoGroupTableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoGroupTableView.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | 12 | @objc protocol PhotoGroupTableDelegate { 13 | func didSelectPhotoGroupTableRowCallBack(_ assetCollection : PHAssetCollection) 14 | } 15 | 16 | class PhotoGroupTableView: UITableView,UITableViewDataSource,UITableViewDelegate { 17 | var tableCellIdentifier = "PhotoGroupCell" 18 | var groups = [PhotoGroupItem]() 19 | var assetsFetchResults = NSMutableArray(capacity: 0) 20 | var totleCount = 0 21 | weak var photoGroupDelegate : PhotoGroupTableDelegate? 22 | 23 | func setUpSelf(_ rect : CGRect){ 24 | frame = rect 25 | backgroundColor = UIColor.clear 26 | separatorStyle = .singleLine 27 | separatorInset = UIEdgeInsetsMake(0, -120, 0, -120) 28 | register(PhotoGroupCell.self, forCellReuseIdentifier: tableCellIdentifier) 29 | delegate = self 30 | dataSource = self 31 | setDataSource() 32 | } 33 | 34 | func setDataSource() { 35 | 36 | fetchAssetCollections() 37 | } 38 | 39 | func fetchAssetCollections() { 40 | //smart albums 41 | let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .any, options: nil) 42 | //user albums 43 | let albums = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: nil) 44 | 45 | let assetArray = [smartAlbums,albums] 46 | 47 | getAssetsData(assetArray) 48 | } 49 | 50 | func getAssetsData(_ data : Array >) { 51 | var tmpArray = Array() 52 | 53 | for collectionAssets in data { 54 | collectionAssets.enumerateObjects({ (collection, start, stop) in 55 | tmpArray.append(collection) 56 | }) 57 | } 58 | self.assetsFetchResults.addObjects(from: tmpArray); 59 | self.reloadData() 60 | } 61 | 62 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{ 63 | return 60 64 | } 65 | 66 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 67 | { 68 | return self.assetsFetchResults.count 69 | } 70 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 71 | let cell = tableView.dequeueReusableCell(withIdentifier: tableCellIdentifier, for: indexPath) as! PhotoGroupCell 72 | 73 | let assetCollection = self.assetsFetchResults.object(at: indexPath.row) 74 | cell.reloadCellWithPHAssetCollection(assetCollection: assetCollection as! PHAssetCollection) 75 | return cell 76 | } 77 | 78 | func numberOfSections(in tableView: UITableView) -> Int { 79 | return 1 80 | } 81 | 82 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 83 | let assetCollection = self.assetsFetchResults.object(at: indexPath.row) 84 | if let target = photoGroupDelegate { 85 | target.didSelectPhotoGroupTableRowCallBack(assetCollection as! PHAssetCollection) 86 | } 87 | } 88 | 89 | } 90 | extension PhotoGroupTableView{ 91 | func showAlert() { 92 | let mainInfoDictory = Bundle.main.infoDictionary! 93 | 94 | let appName = mainInfoDictory["CFBundleName"] as! String 95 | let alertController = UIAlertController(title: "提示",message: "请前往设置->隐私->照片,允许该" + appName + "使用获取相册功能", preferredStyle: UIAlertControllerStyle.alert) 96 | let okAction = UIAlertAction(title: "去设置", style: UIAlertActionStyle.default,handler: { action in 97 | let openUrl = URL(string: UIApplicationOpenSettingsURLString) 98 | if UIApplication.shared.canOpenURL(openUrl!){ 99 | UIApplication.shared.openURL(openUrl!) 100 | } 101 | }) 102 | let cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.default,handler: { action in 103 | 104 | }) 105 | alertController.addAction(cancelAction) 106 | alertController.addAction(okAction) 107 | let rootViewController = UIApplication.shared.keyWindow?.rootViewController 108 | rootViewController!.present(alertController, animated: true, completion: nil) 109 | 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /XYPhoto.xcodeproj/xcuserdata/jiaxiaoyan.xcuserdatad/xcschemes/XYPhoto.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Untitled Diagram.xml: -------------------------------------------------------------------------------- 1 | 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 -------------------------------------------------------------------------------- /XYPhoto/Controller/PhotoLibaryViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoLibaryViewController.swift 3 | // XYPhoto 4 | // 5 | // Created by jiaxiaoyan on 16/7/20. 6 | // Copyright © 2016年 jiaxiaoyan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Photos 11 | class PhotoLibaryViewController: UIViewController ,PHPhotoLibraryChangeObserver{ 12 | 13 | var assetCollection : PHAssetCollection? 14 | var collectionView : PhotoLibaryCollectionView! 15 | var navTitle = "" 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | view.backgroundColor = UIColor.blue 20 | 21 | setnav() 22 | 23 | let style = readCustomStyle() 24 | 25 | let collectionViewFollowLayout = UICollectionViewFlowLayout() 26 | let screenWidth = UIScreen.main.bounds.width 27 | let margin :CGFloat = 1 28 | let edge :CGFloat = 2 29 | 30 | if style.isEqual(to: NSString.init(string: "defaultStyle") as String) { 31 | let width = (screenWidth - margin*CGFloat(3) - edge*CGFloat(2))/CGFloat(4) 32 | collectionViewFollowLayout.itemSize = CGSize(width: width,height: width) 33 | }else if style.isEqual(to: NSString.init(string: "styleOne") as String) { 34 | let width = screenWidth - edge*CGFloat(2) 35 | collectionViewFollowLayout.itemSize = CGSize(width: width,height: width) 36 | } 37 | else if style.isEqual(to: NSString.init(string: "styleTwo") as String) { 38 | let width = (screenWidth - margin*CGFloat(1) - edge*CGFloat(2))/CGFloat(2) 39 | collectionViewFollowLayout.itemSize = CGSize(width: width,height: width) 40 | }else{ 41 | let width = (screenWidth - margin*CGFloat(2) - edge*CGFloat(2))/CGFloat(3) 42 | collectionViewFollowLayout.itemSize = CGSize(width: width,height: width) 43 | } 44 | 45 | collectionViewFollowLayout.minimumLineSpacing = CGFloat(2) 46 | collectionViewFollowLayout.minimumInteritemSpacing = CGFloat(0) 47 | let rect = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) 48 | 49 | collectionView = PhotoLibaryCollectionView(frame: rect, collectionViewLayout: collectionViewFollowLayout) 50 | if let assetCollection = assetCollection { 51 | collectionView.setUpAssetCollection(assetCollection) 52 | title = navTitle 53 | }else{ 54 | let cameraRollAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil) 55 | getGroupData(cameraRollAlbums as! PHFetchResult) 56 | } 57 | view.addSubview(collectionView) 58 | 59 | } 60 | func readCustomStyle() -> NSString { 61 | let customFilePath = Bundle.main.path(forResource: "CustomSetting", ofType: "plist") 62 | let dataDic = NSDictionary(contentsOfFile: customFilePath!); 63 | let albumDic = dataDic?.object(forKey: "albums") as? NSDictionary 64 | var style : NSString = "" 65 | for dic in albumDic! { 66 | let value = dic.value as? Bool 67 | if (value!){ 68 | style = dic.key as! NSString 69 | print(style) 70 | break 71 | } 72 | } 73 | return style 74 | } 75 | func setnav() { 76 | let backButton = UIButton(type: .custom) 77 | backButton.frame = CGRect(x: 0, y: 0, width: 70, height: 44) 78 | backButton.backgroundColor = UIColor.clear 79 | backButton.titleEdgeInsets = UIEdgeInsetsMake(0, -40, 0, 0) 80 | backButton.setImage(UIImage(named: "backIcon"), for: UIControlState()) 81 | backButton.imageEdgeInsets = UIEdgeInsetsMake(0, -40, 0, 0) 82 | backButton.setTitle("返回", for: UIControlState()) 83 | backButton.addTarget(self, action: #selector(PhotoLibaryViewController.backButtonClick), for: .touchUpInside) 84 | 85 | self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: backButton) 86 | 87 | let cancleButton = UIButton(type: .custom) 88 | cancleButton.frame = CGRect(x: 0, y: 0, width: 110, height: 44) 89 | cancleButton.backgroundColor = UIColor.clear 90 | cancleButton.titleEdgeInsets = UIEdgeInsetsMake(0, 40, 0, -40) 91 | cancleButton.setTitle("取消", for: UIControlState()) 92 | cancleButton.setTitleColor(UIColor.white, for: UIControlState()) 93 | cancleButton.addTarget(self, action: #selector(PhotoLibaryViewController.cancleButtonClick), for: .touchUpInside) 94 | self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: cancleButton) 95 | } 96 | 97 | func backButtonClick() { 98 | 99 | self.navigationController?.popViewController(animated: true) 100 | } 101 | 102 | func getGroupData(_ phAssestResult :PHFetchResult) { 103 | 104 | weak var weakSelf = self 105 | 106 | phAssestResult.enumerateObjects( {(collections, count, success) in 107 | 108 | if let collection = collections as? PHAssetCollection { 109 | weakSelf!.collectionView.setUpAssetCollection(collection) 110 | } 111 | } ) 112 | } 113 | 114 | func cancleButtonClick() { 115 | 116 | self.dismiss(animated: true, completion: nil) 117 | 118 | } 119 | 120 | override func awakeFromNib() { 121 | PHPhotoLibrary.shared().register(self) 122 | } 123 | 124 | func photoLibraryDidChange(_ changeInstance: PHChange){ 125 | 126 | } 127 | deinit { 128 | PHPhotoLibrary.shared().unregisterChangeObserver(self) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /XYPhoto.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E1068ADC1D3F2DC1008A90F9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068ADB1D3F2DC1008A90F9 /* AppDelegate.swift */; }; 11 | E1068ADE1D3F2DC1008A90F9 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068ADD1D3F2DC1008A90F9 /* ViewController.swift */; }; 12 | E1068AE11D3F2DC1008A90F9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E1068ADF1D3F2DC1008A90F9 /* Main.storyboard */; }; 13 | E1068AE31D3F2DC1008A90F9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E1068AE21D3F2DC1008A90F9 /* Assets.xcassets */; }; 14 | E1068AE61D3F2DC1008A90F9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E1068AE41D3F2DC1008A90F9 /* LaunchScreen.storyboard */; }; 15 | E1068AF11D3F2DC1008A90F9 /* XYPhotoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068AF01D3F2DC1008A90F9 /* XYPhotoTests.swift */; }; 16 | E1068AFC1D3F2DC1008A90F9 /* XYPhotoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068AFB1D3F2DC1008A90F9 /* XYPhotoUITests.swift */; }; 17 | E1068B0A1D3F2EA5008A90F9 /* PhotoGroupPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B091D3F2EA5008A90F9 /* PhotoGroupPickerViewController.swift */; }; 18 | E1068B0F1D3F2F62008A90F9 /* PhotoGroupCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B0D1D3F2F62008A90F9 /* PhotoGroupCell.swift */; }; 19 | E1068B131D3F37F2008A90F9 /* PhotoGroupItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B121D3F37F2008A90F9 /* PhotoGroupItem.swift */; }; 20 | E1068B151D3F53AC008A90F9 /* PhotoGroupTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B141D3F53AC008A90F9 /* PhotoGroupTableView.swift */; }; 21 | E1068B1A1D3F5F3E008A90F9 /* PhotoLibaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B191D3F5F3E008A90F9 /* PhotoLibaryViewController.swift */; }; 22 | E1068B1C1D3F6D03008A90F9 /* NavgationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B1B1D3F6D03008A90F9 /* NavgationViewController.swift */; }; 23 | E1068B1E1D3F7049008A90F9 /* PhotoLibaryCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B1D1D3F7049008A90F9 /* PhotoLibaryCollectionView.swift */; }; 24 | E1068B211D3F70C5008A90F9 /* PhotoLibraryCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068B1F1D3F70C5008A90F9 /* PhotoLibraryCollectionCell.swift */; }; 25 | E12C49DF1F500CB400E5C707 /* CustomSetting.plist in Resources */ = {isa = PBXBuildFile; fileRef = E12C49DE1F500CB400E5C707 /* CustomSetting.plist */; }; 26 | E14AF3701D475B6400B2A49A /* PhotoLibraryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E14AF36F1D475B6400B2A49A /* PhotoLibraryManager.swift */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | E1068AED1D3F2DC1008A90F9 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = E1068AD01D3F2DC1008A90F9 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = E1068AD71D3F2DC1008A90F9; 35 | remoteInfo = XYPhoto; 36 | }; 37 | E1068AF81D3F2DC1008A90F9 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = E1068AD01D3F2DC1008A90F9 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = E1068AD71D3F2DC1008A90F9; 42 | remoteInfo = XYPhoto; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | E1068AD81D3F2DC1008A90F9 /* XYPhoto.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XYPhoto.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | E1068ADB1D3F2DC1008A90F9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 49 | E1068ADD1D3F2DC1008A90F9 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = ../ViewController.swift; sourceTree = ""; }; 50 | E1068AE01D3F2DC1008A90F9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | E1068AE21D3F2DC1008A90F9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | E1068AE51D3F2DC1008A90F9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | E1068AE71D3F2DC1008A90F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | E1068AEC1D3F2DC1008A90F9 /* XYPhotoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XYPhotoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | E1068AF01D3F2DC1008A90F9 /* XYPhotoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XYPhotoTests.swift; sourceTree = ""; }; 56 | E1068AF21D3F2DC1008A90F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | E1068AF71D3F2DC1008A90F9 /* XYPhotoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = XYPhotoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | E1068AFB1D3F2DC1008A90F9 /* XYPhotoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XYPhotoUITests.swift; sourceTree = ""; }; 59 | E1068AFD1D3F2DC1008A90F9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | E1068B091D3F2EA5008A90F9 /* PhotoGroupPickerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PhotoGroupPickerViewController.swift; path = ../PhotoGroupPickerViewController.swift; sourceTree = ""; }; 61 | E1068B0D1D3F2F62008A90F9 /* PhotoGroupCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PhotoGroupCell.swift; path = ../PhotoGroupCell.swift; sourceTree = ""; }; 62 | E1068B121D3F37F2008A90F9 /* PhotoGroupItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoGroupItem.swift; sourceTree = ""; }; 63 | E1068B141D3F53AC008A90F9 /* PhotoGroupTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PhotoGroupTableView.swift; path = ../PhotoGroupTableView.swift; sourceTree = ""; }; 64 | E1068B191D3F5F3E008A90F9 /* PhotoLibaryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoLibaryViewController.swift; sourceTree = ""; }; 65 | E1068B1B1D3F6D03008A90F9 /* NavgationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavgationViewController.swift; sourceTree = ""; }; 66 | E1068B1D1D3F7049008A90F9 /* PhotoLibaryCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoLibaryCollectionView.swift; sourceTree = ""; }; 67 | E1068B1F1D3F70C5008A90F9 /* PhotoLibraryCollectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoLibraryCollectionCell.swift; sourceTree = ""; }; 68 | E12C49DE1F500CB400E5C707 /* CustomSetting.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = CustomSetting.plist; sourceTree = ""; }; 69 | E14AF36F1D475B6400B2A49A /* PhotoLibraryManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoLibraryManager.swift; sourceTree = ""; }; 70 | E1D76EE21F5EB0570006253B /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 71 | E1D76EE31F5EB0570006253B /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; 72 | /* End PBXFileReference section */ 73 | 74 | /* Begin PBXFrameworksBuildPhase section */ 75 | E1068AD51D3F2DC1008A90F9 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | E1068AE91D3F2DC1008A90F9 /* Frameworks */ = { 83 | isa = PBXFrameworksBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | E1068AF41D3F2DC1008A90F9 /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | /* End PBXFrameworksBuildPhase section */ 97 | 98 | /* Begin PBXGroup section */ 99 | E1068ACF1D3F2DC1008A90F9 = { 100 | isa = PBXGroup; 101 | children = ( 102 | E1068ADA1D3F2DC1008A90F9 /* XYPhoto */, 103 | E1068AEF1D3F2DC1008A90F9 /* XYPhotoTests */, 104 | E1068AFA1D3F2DC1008A90F9 /* XYPhotoUITests */, 105 | E1068AD91D3F2DC1008A90F9 /* Products */, 106 | ); 107 | sourceTree = ""; 108 | }; 109 | E1068AD91D3F2DC1008A90F9 /* Products */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | E1068AD81D3F2DC1008A90F9 /* XYPhoto.app */, 113 | E1068AEC1D3F2DC1008A90F9 /* XYPhotoTests.xctest */, 114 | E1068AF71D3F2DC1008A90F9 /* XYPhotoUITests.xctest */, 115 | ); 116 | name = Products; 117 | sourceTree = ""; 118 | }; 119 | E1068ADA1D3F2DC1008A90F9 /* XYPhoto */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | E12C49DD1F500CB400E5C707 /* CustomSettings */, 123 | E1068ADB1D3F2DC1008A90F9 /* AppDelegate.swift */, 124 | E14AF36E1D475B4A00B2A49A /* Tool */, 125 | E1068B181D3F5EF1008A90F9 /* Module */, 126 | E1068B171D3F5ECB008A90F9 /* Controller */, 127 | E1068B161D3F584D008A90F9 /* View */, 128 | E1068B111D3F37D8008A90F9 /* Model */, 129 | E1068ADF1D3F2DC1008A90F9 /* Main.storyboard */, 130 | E1068AE21D3F2DC1008A90F9 /* Assets.xcassets */, 131 | E1068AE41D3F2DC1008A90F9 /* LaunchScreen.storyboard */, 132 | E1068AE71D3F2DC1008A90F9 /* Info.plist */, 133 | ); 134 | path = XYPhoto; 135 | sourceTree = ""; 136 | }; 137 | E1068AEF1D3F2DC1008A90F9 /* XYPhotoTests */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | E1068AF01D3F2DC1008A90F9 /* XYPhotoTests.swift */, 141 | E1068AF21D3F2DC1008A90F9 /* Info.plist */, 142 | ); 143 | path = XYPhotoTests; 144 | sourceTree = ""; 145 | }; 146 | E1068AFA1D3F2DC1008A90F9 /* XYPhotoUITests */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | E1068AFB1D3F2DC1008A90F9 /* XYPhotoUITests.swift */, 150 | E1068AFD1D3F2DC1008A90F9 /* Info.plist */, 151 | ); 152 | path = XYPhotoUITests; 153 | sourceTree = ""; 154 | }; 155 | E1068B111D3F37D8008A90F9 /* Model */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | E1068B121D3F37F2008A90F9 /* PhotoGroupItem.swift */, 159 | ); 160 | path = Model; 161 | sourceTree = ""; 162 | }; 163 | E1068B161D3F584D008A90F9 /* View */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | E1068B0D1D3F2F62008A90F9 /* PhotoGroupCell.swift */, 167 | E1068B1F1D3F70C5008A90F9 /* PhotoLibraryCollectionCell.swift */, 168 | ); 169 | path = View; 170 | sourceTree = ""; 171 | }; 172 | E1068B171D3F5ECB008A90F9 /* Controller */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | E1068ADD1D3F2DC1008A90F9 /* ViewController.swift */, 176 | E1068B1B1D3F6D03008A90F9 /* NavgationViewController.swift */, 177 | E1068B091D3F2EA5008A90F9 /* PhotoGroupPickerViewController.swift */, 178 | E1068B191D3F5F3E008A90F9 /* PhotoLibaryViewController.swift */, 179 | ); 180 | path = Controller; 181 | sourceTree = ""; 182 | }; 183 | E1068B181D3F5EF1008A90F9 /* Module */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | E1068B141D3F53AC008A90F9 /* PhotoGroupTableView.swift */, 187 | E1068B1D1D3F7049008A90F9 /* PhotoLibaryCollectionView.swift */, 188 | ); 189 | path = Module; 190 | sourceTree = ""; 191 | }; 192 | E12C49DD1F500CB400E5C707 /* CustomSettings */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | E12C49DE1F500CB400E5C707 /* CustomSetting.plist */, 196 | ); 197 | path = CustomSettings; 198 | sourceTree = ""; 199 | }; 200 | E14AF36E1D475B4A00B2A49A /* Tool */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | E14AF36F1D475B6400B2A49A /* PhotoLibraryManager.swift */, 204 | ); 205 | path = Tool; 206 | sourceTree = ""; 207 | }; 208 | /* End PBXGroup section */ 209 | 210 | /* Begin PBXNativeTarget section */ 211 | E1068AD71D3F2DC1008A90F9 /* XYPhoto */ = { 212 | isa = PBXNativeTarget; 213 | buildConfigurationList = E1068B001D3F2DC1008A90F9 /* Build configuration list for PBXNativeTarget "XYPhoto" */; 214 | buildPhases = ( 215 | E1068AD41D3F2DC1008A90F9 /* Sources */, 216 | E1068AD51D3F2DC1008A90F9 /* Frameworks */, 217 | E1068AD61D3F2DC1008A90F9 /* Resources */, 218 | ); 219 | buildRules = ( 220 | ); 221 | dependencies = ( 222 | ); 223 | name = XYPhoto; 224 | productName = XYPhoto; 225 | productReference = E1068AD81D3F2DC1008A90F9 /* XYPhoto.app */; 226 | productType = "com.apple.product-type.application"; 227 | }; 228 | E1068AEB1D3F2DC1008A90F9 /* XYPhotoTests */ = { 229 | isa = PBXNativeTarget; 230 | buildConfigurationList = E1068B031D3F2DC1008A90F9 /* Build configuration list for PBXNativeTarget "XYPhotoTests" */; 231 | buildPhases = ( 232 | E1068AE81D3F2DC1008A90F9 /* Sources */, 233 | E1068AE91D3F2DC1008A90F9 /* Frameworks */, 234 | E1068AEA1D3F2DC1008A90F9 /* Resources */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | E1068AEE1D3F2DC1008A90F9 /* PBXTargetDependency */, 240 | ); 241 | name = XYPhotoTests; 242 | productName = XYPhotoTests; 243 | productReference = E1068AEC1D3F2DC1008A90F9 /* XYPhotoTests.xctest */; 244 | productType = "com.apple.product-type.bundle.unit-test"; 245 | }; 246 | E1068AF61D3F2DC1008A90F9 /* XYPhotoUITests */ = { 247 | isa = PBXNativeTarget; 248 | buildConfigurationList = E1068B061D3F2DC1008A90F9 /* Build configuration list for PBXNativeTarget "XYPhotoUITests" */; 249 | buildPhases = ( 250 | E1068AF31D3F2DC1008A90F9 /* Sources */, 251 | E1068AF41D3F2DC1008A90F9 /* Frameworks */, 252 | E1068AF51D3F2DC1008A90F9 /* Resources */, 253 | ); 254 | buildRules = ( 255 | ); 256 | dependencies = ( 257 | E1068AF91D3F2DC1008A90F9 /* PBXTargetDependency */, 258 | ); 259 | name = XYPhotoUITests; 260 | productName = XYPhotoUITests; 261 | productReference = E1068AF71D3F2DC1008A90F9 /* XYPhotoUITests.xctest */; 262 | productType = "com.apple.product-type.bundle.ui-testing"; 263 | }; 264 | /* End PBXNativeTarget section */ 265 | 266 | /* Begin PBXProject section */ 267 | E1068AD01D3F2DC1008A90F9 /* Project object */ = { 268 | isa = PBXProject; 269 | attributes = { 270 | LastSwiftUpdateCheck = 0730; 271 | LastUpgradeCheck = 0730; 272 | ORGANIZATIONNAME = jiaxiaoyan; 273 | TargetAttributes = { 274 | E1068AD71D3F2DC1008A90F9 = { 275 | CreatedOnToolsVersion = 7.3.1; 276 | DevelopmentTeam = V76G292Y67; 277 | LastSwiftMigration = 0830; 278 | }; 279 | E1068AEB1D3F2DC1008A90F9 = { 280 | CreatedOnToolsVersion = 7.3.1; 281 | LastSwiftMigration = 0830; 282 | TestTargetID = E1068AD71D3F2DC1008A90F9; 283 | }; 284 | E1068AF61D3F2DC1008A90F9 = { 285 | CreatedOnToolsVersion = 7.3.1; 286 | LastSwiftMigration = 0830; 287 | TestTargetID = E1068AD71D3F2DC1008A90F9; 288 | }; 289 | }; 290 | }; 291 | buildConfigurationList = E1068AD31D3F2DC1008A90F9 /* Build configuration list for PBXProject "XYPhoto" */; 292 | compatibilityVersion = "Xcode 3.2"; 293 | developmentRegion = English; 294 | hasScannedForEncodings = 0; 295 | knownRegions = ( 296 | en, 297 | Base, 298 | ); 299 | mainGroup = E1068ACF1D3F2DC1008A90F9; 300 | productRefGroup = E1068AD91D3F2DC1008A90F9 /* Products */; 301 | projectDirPath = ""; 302 | projectRoot = ""; 303 | targets = ( 304 | E1068AD71D3F2DC1008A90F9 /* XYPhoto */, 305 | E1068AEB1D3F2DC1008A90F9 /* XYPhotoTests */, 306 | E1068AF61D3F2DC1008A90F9 /* XYPhotoUITests */, 307 | ); 308 | }; 309 | /* End PBXProject section */ 310 | 311 | /* Begin PBXResourcesBuildPhase section */ 312 | E1068AD61D3F2DC1008A90F9 /* Resources */ = { 313 | isa = PBXResourcesBuildPhase; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | E12C49DF1F500CB400E5C707 /* CustomSetting.plist in Resources */, 317 | E1068AE61D3F2DC1008A90F9 /* LaunchScreen.storyboard in Resources */, 318 | E1068AE31D3F2DC1008A90F9 /* Assets.xcassets in Resources */, 319 | E1068AE11D3F2DC1008A90F9 /* Main.storyboard in Resources */, 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | E1068AEA1D3F2DC1008A90F9 /* Resources */ = { 324 | isa = PBXResourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | E1068AF51D3F2DC1008A90F9 /* Resources */ = { 331 | isa = PBXResourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | /* End PBXResourcesBuildPhase section */ 338 | 339 | /* Begin PBXSourcesBuildPhase section */ 340 | E1068AD41D3F2DC1008A90F9 /* Sources */ = { 341 | isa = PBXSourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | E1068B151D3F53AC008A90F9 /* PhotoGroupTableView.swift in Sources */, 345 | E1068B131D3F37F2008A90F9 /* PhotoGroupItem.swift in Sources */, 346 | E1068ADE1D3F2DC1008A90F9 /* ViewController.swift in Sources */, 347 | E14AF3701D475B6400B2A49A /* PhotoLibraryManager.swift in Sources */, 348 | E1068B0A1D3F2EA5008A90F9 /* PhotoGroupPickerViewController.swift in Sources */, 349 | E1068B0F1D3F2F62008A90F9 /* PhotoGroupCell.swift in Sources */, 350 | E1068B1E1D3F7049008A90F9 /* PhotoLibaryCollectionView.swift in Sources */, 351 | E1068B211D3F70C5008A90F9 /* PhotoLibraryCollectionCell.swift in Sources */, 352 | E1068ADC1D3F2DC1008A90F9 /* AppDelegate.swift in Sources */, 353 | E1068B1C1D3F6D03008A90F9 /* NavgationViewController.swift in Sources */, 354 | E1068B1A1D3F5F3E008A90F9 /* PhotoLibaryViewController.swift in Sources */, 355 | ); 356 | runOnlyForDeploymentPostprocessing = 0; 357 | }; 358 | E1068AE81D3F2DC1008A90F9 /* Sources */ = { 359 | isa = PBXSourcesBuildPhase; 360 | buildActionMask = 2147483647; 361 | files = ( 362 | E1068AF11D3F2DC1008A90F9 /* XYPhotoTests.swift in Sources */, 363 | ); 364 | runOnlyForDeploymentPostprocessing = 0; 365 | }; 366 | E1068AF31D3F2DC1008A90F9 /* Sources */ = { 367 | isa = PBXSourcesBuildPhase; 368 | buildActionMask = 2147483647; 369 | files = ( 370 | E1068AFC1D3F2DC1008A90F9 /* XYPhotoUITests.swift in Sources */, 371 | ); 372 | runOnlyForDeploymentPostprocessing = 0; 373 | }; 374 | /* End PBXSourcesBuildPhase section */ 375 | 376 | /* Begin PBXTargetDependency section */ 377 | E1068AEE1D3F2DC1008A90F9 /* PBXTargetDependency */ = { 378 | isa = PBXTargetDependency; 379 | target = E1068AD71D3F2DC1008A90F9 /* XYPhoto */; 380 | targetProxy = E1068AED1D3F2DC1008A90F9 /* PBXContainerItemProxy */; 381 | }; 382 | E1068AF91D3F2DC1008A90F9 /* PBXTargetDependency */ = { 383 | isa = PBXTargetDependency; 384 | target = E1068AD71D3F2DC1008A90F9 /* XYPhoto */; 385 | targetProxy = E1068AF81D3F2DC1008A90F9 /* PBXContainerItemProxy */; 386 | }; 387 | /* End PBXTargetDependency section */ 388 | 389 | /* Begin PBXVariantGroup section */ 390 | E1068ADF1D3F2DC1008A90F9 /* Main.storyboard */ = { 391 | isa = PBXVariantGroup; 392 | children = ( 393 | E1068AE01D3F2DC1008A90F9 /* Base */, 394 | E1D76EE21F5EB0570006253B /* zh-Hans */, 395 | ); 396 | name = Main.storyboard; 397 | sourceTree = ""; 398 | }; 399 | E1068AE41D3F2DC1008A90F9 /* LaunchScreen.storyboard */ = { 400 | isa = PBXVariantGroup; 401 | children = ( 402 | E1068AE51D3F2DC1008A90F9 /* Base */, 403 | E1D76EE31F5EB0570006253B /* zh-Hans */, 404 | ); 405 | name = LaunchScreen.storyboard; 406 | sourceTree = ""; 407 | }; 408 | /* End PBXVariantGroup section */ 409 | 410 | /* Begin XCBuildConfiguration section */ 411 | E1068AFE1D3F2DC1008A90F9 /* Debug */ = { 412 | isa = XCBuildConfiguration; 413 | buildSettings = { 414 | ALWAYS_SEARCH_USER_PATHS = NO; 415 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 416 | CLANG_ANALYZER_NONNULL = YES; 417 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 418 | CLANG_CXX_LIBRARY = "libc++"; 419 | CLANG_ENABLE_MODULES = YES; 420 | CLANG_ENABLE_OBJC_ARC = YES; 421 | CLANG_WARN_BOOL_CONVERSION = YES; 422 | CLANG_WARN_CONSTANT_CONVERSION = YES; 423 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 424 | CLANG_WARN_EMPTY_BODY = YES; 425 | CLANG_WARN_ENUM_CONVERSION = YES; 426 | CLANG_WARN_INT_CONVERSION = YES; 427 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 428 | CLANG_WARN_UNREACHABLE_CODE = YES; 429 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 430 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 431 | COPY_PHASE_STRIP = NO; 432 | DEBUG_INFORMATION_FORMAT = dwarf; 433 | ENABLE_STRICT_OBJC_MSGSEND = YES; 434 | ENABLE_TESTABILITY = YES; 435 | GCC_C_LANGUAGE_STANDARD = gnu99; 436 | GCC_DYNAMIC_NO_PIC = NO; 437 | GCC_NO_COMMON_BLOCKS = YES; 438 | GCC_OPTIMIZATION_LEVEL = 0; 439 | GCC_PREPROCESSOR_DEFINITIONS = ( 440 | "DEBUG=1", 441 | "$(inherited)", 442 | ); 443 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 444 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 445 | GCC_WARN_UNDECLARED_SELECTOR = YES; 446 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 447 | GCC_WARN_UNUSED_FUNCTION = YES; 448 | GCC_WARN_UNUSED_VARIABLE = YES; 449 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 450 | MTL_ENABLE_DEBUG_INFO = YES; 451 | ONLY_ACTIVE_ARCH = YES; 452 | SDKROOT = iphoneos; 453 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 454 | TARGETED_DEVICE_FAMILY = "1,2"; 455 | }; 456 | name = Debug; 457 | }; 458 | E1068AFF1D3F2DC1008A90F9 /* Release */ = { 459 | isa = XCBuildConfiguration; 460 | buildSettings = { 461 | ALWAYS_SEARCH_USER_PATHS = NO; 462 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 463 | CLANG_ANALYZER_NONNULL = YES; 464 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 465 | CLANG_CXX_LIBRARY = "libc++"; 466 | CLANG_ENABLE_MODULES = YES; 467 | CLANG_ENABLE_OBJC_ARC = YES; 468 | CLANG_WARN_BOOL_CONVERSION = YES; 469 | CLANG_WARN_CONSTANT_CONVERSION = YES; 470 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 471 | CLANG_WARN_EMPTY_BODY = YES; 472 | CLANG_WARN_ENUM_CONVERSION = YES; 473 | CLANG_WARN_INT_CONVERSION = YES; 474 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 475 | CLANG_WARN_UNREACHABLE_CODE = YES; 476 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 477 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 478 | COPY_PHASE_STRIP = NO; 479 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 480 | ENABLE_NS_ASSERTIONS = NO; 481 | ENABLE_STRICT_OBJC_MSGSEND = YES; 482 | GCC_C_LANGUAGE_STANDARD = gnu99; 483 | GCC_NO_COMMON_BLOCKS = YES; 484 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 485 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 486 | GCC_WARN_UNDECLARED_SELECTOR = YES; 487 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 488 | GCC_WARN_UNUSED_FUNCTION = YES; 489 | GCC_WARN_UNUSED_VARIABLE = YES; 490 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 491 | MTL_ENABLE_DEBUG_INFO = NO; 492 | SDKROOT = iphoneos; 493 | TARGETED_DEVICE_FAMILY = "1,2"; 494 | VALIDATE_PRODUCT = YES; 495 | }; 496 | name = Release; 497 | }; 498 | E1068B011D3F2DC1008A90F9 /* Debug */ = { 499 | isa = XCBuildConfiguration; 500 | buildSettings = { 501 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 502 | CODE_SIGN_IDENTITY = "iPhone Developer"; 503 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 504 | DEVELOPMENT_TEAM = V76G292Y67; 505 | INFOPLIST_FILE = XYPhoto/Info.plist; 506 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 507 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 508 | PRODUCT_BUNDLE_IDENTIFIER = com.syswin.www; 509 | PRODUCT_NAME = "$(TARGET_NAME)"; 510 | PROVISIONING_PROFILE = ""; 511 | SWIFT_VERSION = 3.0; 512 | }; 513 | name = Debug; 514 | }; 515 | E1068B021D3F2DC1008A90F9 /* Release */ = { 516 | isa = XCBuildConfiguration; 517 | buildSettings = { 518 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 519 | CODE_SIGN_IDENTITY = "iPhone Developer"; 520 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 521 | DEVELOPMENT_TEAM = V76G292Y67; 522 | INFOPLIST_FILE = XYPhoto/Info.plist; 523 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 524 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 525 | PRODUCT_BUNDLE_IDENTIFIER = com.syswin.www; 526 | PRODUCT_NAME = "$(TARGET_NAME)"; 527 | PROVISIONING_PROFILE = ""; 528 | SWIFT_VERSION = 3.0; 529 | }; 530 | name = Release; 531 | }; 532 | E1068B041D3F2DC1008A90F9 /* Debug */ = { 533 | isa = XCBuildConfiguration; 534 | buildSettings = { 535 | BUNDLE_LOADER = "$(TEST_HOST)"; 536 | INFOPLIST_FILE = XYPhotoTests/Info.plist; 537 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 538 | PRODUCT_BUNDLE_IDENTIFIER = com.personalProject.www.XYPhotoTests; 539 | PRODUCT_NAME = "$(TARGET_NAME)"; 540 | SWIFT_VERSION = 3.0; 541 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/XYPhoto.app/XYPhoto"; 542 | }; 543 | name = Debug; 544 | }; 545 | E1068B051D3F2DC1008A90F9 /* Release */ = { 546 | isa = XCBuildConfiguration; 547 | buildSettings = { 548 | BUNDLE_LOADER = "$(TEST_HOST)"; 549 | INFOPLIST_FILE = XYPhotoTests/Info.plist; 550 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 551 | PRODUCT_BUNDLE_IDENTIFIER = com.personalProject.www.XYPhotoTests; 552 | PRODUCT_NAME = "$(TARGET_NAME)"; 553 | SWIFT_VERSION = 3.0; 554 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/XYPhoto.app/XYPhoto"; 555 | }; 556 | name = Release; 557 | }; 558 | E1068B071D3F2DC1008A90F9 /* Debug */ = { 559 | isa = XCBuildConfiguration; 560 | buildSettings = { 561 | INFOPLIST_FILE = XYPhotoUITests/Info.plist; 562 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 563 | PRODUCT_BUNDLE_IDENTIFIER = com.personalProject.www.XYPhotoUITests; 564 | PRODUCT_NAME = "$(TARGET_NAME)"; 565 | SWIFT_VERSION = 3.0; 566 | TEST_TARGET_NAME = XYPhoto; 567 | }; 568 | name = Debug; 569 | }; 570 | E1068B081D3F2DC1008A90F9 /* Release */ = { 571 | isa = XCBuildConfiguration; 572 | buildSettings = { 573 | INFOPLIST_FILE = XYPhotoUITests/Info.plist; 574 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 575 | PRODUCT_BUNDLE_IDENTIFIER = com.personalProject.www.XYPhotoUITests; 576 | PRODUCT_NAME = "$(TARGET_NAME)"; 577 | SWIFT_VERSION = 3.0; 578 | TEST_TARGET_NAME = XYPhoto; 579 | }; 580 | name = Release; 581 | }; 582 | /* End XCBuildConfiguration section */ 583 | 584 | /* Begin XCConfigurationList section */ 585 | E1068AD31D3F2DC1008A90F9 /* Build configuration list for PBXProject "XYPhoto" */ = { 586 | isa = XCConfigurationList; 587 | buildConfigurations = ( 588 | E1068AFE1D3F2DC1008A90F9 /* Debug */, 589 | E1068AFF1D3F2DC1008A90F9 /* Release */, 590 | ); 591 | defaultConfigurationIsVisible = 0; 592 | defaultConfigurationName = Release; 593 | }; 594 | E1068B001D3F2DC1008A90F9 /* Build configuration list for PBXNativeTarget "XYPhoto" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | E1068B011D3F2DC1008A90F9 /* Debug */, 598 | E1068B021D3F2DC1008A90F9 /* Release */, 599 | ); 600 | defaultConfigurationIsVisible = 0; 601 | defaultConfigurationName = Release; 602 | }; 603 | E1068B031D3F2DC1008A90F9 /* Build configuration list for PBXNativeTarget "XYPhotoTests" */ = { 604 | isa = XCConfigurationList; 605 | buildConfigurations = ( 606 | E1068B041D3F2DC1008A90F9 /* Debug */, 607 | E1068B051D3F2DC1008A90F9 /* Release */, 608 | ); 609 | defaultConfigurationIsVisible = 0; 610 | defaultConfigurationName = Release; 611 | }; 612 | E1068B061D3F2DC1008A90F9 /* Build configuration list for PBXNativeTarget "XYPhotoUITests" */ = { 613 | isa = XCConfigurationList; 614 | buildConfigurations = ( 615 | E1068B071D3F2DC1008A90F9 /* Debug */, 616 | E1068B081D3F2DC1008A90F9 /* Release */, 617 | ); 618 | defaultConfigurationIsVisible = 0; 619 | defaultConfigurationName = Release; 620 | }; 621 | /* End XCConfigurationList section */ 622 | }; 623 | rootObject = E1068AD01D3F2DC1008A90F9 /* Project object */; 624 | } 625 | --------------------------------------------------------------------------------