꾸준히 안타치기

사진첩에서 이미지 가져오기 / 삭제하기 본문

iOS/storyboard & code

사진첩에서 이미지 가져오기 / 삭제하기

글자줍기 2021. 12. 26. 15:16
반응형

사진첩에서 이미지 가져오기

테이블뷰에 사진첩에 있는 사진 가져와서 보여주기.

0. PhotoViewController를 생성한다.

1. Photos 프레임 워크를 임포트한다.

2.  requeseCollection() 카메라롤을 가지고 오는 함수를 작성한다.

3.. 테이블을 등록하고, 테이블뷰 셀설정을 해준다.  셀설정안에서 cell의 index를 가져온다. 이미지 매니저로 사진을 요청한다.

4. 뷰가 로드 되었을때 보일 case를 작성한다. 허용되었을때만, 데이터를 다시 불러온다.

5. 스토리보드로가서 인터페이스를 작성한다. 테이블뷰를 작성한다. 셀을 올린다. identifier값에 cell이라고 작성 

6. 스토리보드에서 테이블뷰에 -> 데이터 소스를 쭉끌어 뷰컨트롤러와 연결한다. 

7. 뷰컨트롤러에 -> tableView를 쭉끌어와 연결한다.

8. info.plist에 프라이버시 문구를 작성해줘야한다. AddRow하고, Privacy Photo...~  String에 사진첩 접근이유를 작성한다.

 

import UIKit
// Photos프레임웍 import
import Photos

class PhotoViewController: UIViewController, UITableViewDataSource{
    // 테이블뷰 설정
    @IBOutlet weak var tableView: UITableView!
    // 카메라롤에서 가져온 fetchResult
    var fetchResult: PHFetchResult<PHAsset>!
    // 가져온에셋을 가지고 이미지를 로드해옴
    let imageManager: PHCachingImageManager = PHCachingImageManager()
    // 셀이름
    let cellIdendifier: String = "cell"
    
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.fetchResult?.count ?? 0
    }
    
    // 테이블 뷰 셀 설정
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: self.cellIdendifier, for: indexPath)
        
        // cell의 index를 가져옴
        let asset: PHAsset = fetchResult.object(at: indexPath.row)
        // 이미지매니저로 사진 요청
        imageManager.requestImage(for: asset,
                                  targetSize: CGSize(width: 30, height: 30),
                                  contentMode: .aspectFill,
                                  options: nil,
                                  resultHandler: { image, _ in
                                    cell.imageView?.image = image
                                  })
        return cell
    }
    
    
    // 카메라롤 가지고 오기
    func requestCollection(){
        
        let cameraRoll: PHFetchResult<PHAssetCollection> = PHAssetCollection.fetchAssetCollections(with: .smartAlbum,
                                                                                                   subtype: .smartAlbumUserLibrary, options: nil)
    
        guard let cameraRollCollection = cameraRoll.firstObject else {
            return
        }
        
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        self.fetchResult = PHAsset.fetchAssets(in: cameraRollCollection, options: fetchOptions)
        
    }
    
    
    // 뷰가 로드 되었을때
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        let photoAurhorizationStatus = PHPhotoLibrary.authorizationStatus()
        
        switch photoAurhorizationStatus {
        case .authorized:
            print("접근 허가됨")
            self.requestCollection()
            // 데이터 다시 불러오기
            self.tableView.reloadData()
        case .denied:
            print("접근 불허")
            self.requestCollection()
        case .notDetermined:
            print("아직 응답하지 않음")
            PHPhotoLibrary.requestAuthorization({ (status) in
                switch status {
                case .authorized:
                    print("사용자가 허용함")
                    self.requestCollection()
                    // 오퍼레이션큐???? 나중에 공부하라고 함
                    OperationQueue.main.addOperation {
                        // 데이터 다시 불러오기
                        self.tableView.reloadData()
                    }
                  
                case .denied:
                    print("사용자가 불허함")
                default: break
                }
            })
        case .restricted:
            print("접근 제한")
        default: break
        }
        PHPhotoLibrary.shared().register(self)
    }
}

 

사진첩에서 이미지  불러오기, 삭제하기 ( 전체소스 ) 

import UIKit
// Photos프레임웍 import
import Photos

class PhotoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate,
                           PHPhotoLibraryChangeObserver{
    // 테이블뷰 설정
    @IBOutlet weak var tableView: UITableView!
    // 카메라롤에서 가져온 fetchResult
    var fetchResult: PHFetchResult<PHAsset>!
    // 가져온에셋을 가지고 이미지를 로드해옴
    let imageManager: PHCachingImageManager = PHCachingImageManager()
    // 셀이름
    let cellIdendifier: String = "cell"
    
    
    /*/ /////////////////////////////////////////////////////////////////////////
      사진첩에서 이미지 삭제 
     */
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) ->
    Bool {
        return true
    }
    
    func tableView(_ tableView: UITableView, commit edittingStyle:
                    UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath){
        if edittingStyle == .delete {
            let asset: PHAsset = self.fetchResult[indexPath.row]
            
            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.deleteAssets([asset] as NSArray)
            }, completionHandler: nil)
        }
    }
    
    func photoLibraryDidChange(_ changeInstance: PHChange) {
        guard let changes = changeInstance.changeDetails(for: fetchResult)
        else{ return }
        
        fetchResult = changes.fetchResultAfterChanges
        
        OperationQueue.main.addOperation {
            self.tableView.reloadSections(IndexSet(0...0), with: .automatic)
        }
    }
    
    
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.fetchResult?.count ?? 0
    }
    
    // 테이블 뷰 셀 설정
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: self.cellIdendifier, for: indexPath)
        
        // cell의 index를 가져옴
        let asset: PHAsset = fetchResult.object(at: indexPath.row)
        // 이미지매니저로 사진 요청
        imageManager.requestImage(for: asset,
                                  targetSize: CGSize(width: 30, height: 30),
                                  contentMode: .aspectFill,
                                  options: nil,
                                  resultHandler: { image, _ in
                                    cell.imageView?.image = image
                                  })
        return cell
    }
    
    
    // 카메라롤 가지고 오기
    func requestCollection(){
        
        let cameraRoll: PHFetchResult<PHAssetCollection> = PHAssetCollection.fetchAssetCollections(with: .smartAlbum,
                                                                                                   subtype: .smartAlbumUserLibrary, options: nil)
    
        guard let cameraRollCollection = cameraRoll.firstObject else {
            return
        }
        
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        self.fetchResult = PHAsset.fetchAssets(in: cameraRollCollection, options: fetchOptions)
        
    }
    
    
    // 뷰가 로드 되었을때
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        let photoAurhorizationStatus = PHPhotoLibrary.authorizationStatus()
        
        switch photoAurhorizationStatus {
        case .authorized:
            print("접근 허가됨")
            self.requestCollection()
            // 데이터 다시 불러오기
            self.tableView.reloadData()
        case .denied:
            print("접근 불허")
            self.requestCollection()
        case .notDetermined:
            print("아직 응답하지 않음")
            PHPhotoLibrary.requestAuthorization({ (status) in
                switch status {
                case .authorized:
                    print("사용자가 허용함")
                    self.requestCollection()
                    // 오퍼레이션큐???? 나중에 공부하라고 함
                    OperationQueue.main.addOperation {
                        // 데이터 다시 불러오기
                        self.tableView.reloadData()
                    }
                  
                case .denied:
                    print("사용자가 불허함")
                default: break
                }
            })
        case .restricted:
            print("접근 제한")
        default: break
        }
        
        PHPhotoLibrary.shared().register(self)

    }

    
}

 

삭제하기 

1. photoViewController에 UITableViewDeledate를 추가한다.

2. tableView에서 편집모드로 들어가 삭제할것인지에 대한 코드를 작성한다.

3. photoViewController에 PHPhotoLibraryChangeObserver를 추가한다. 데이터 변경감지

4. viewDidload에 PhPhotoLibrary.shared().register(self) 한 줄을 추가한다.

 /*/
      사진첩에서 이미지 삭제
     */
    // 테이블뷰를 왼쪽으로 밀어서 삭제할수 있게 함.
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) ->
    Bool {
        return true
    }
    
    // 편집모드로 들어 왔을때 삭제할것인지? 삭제한다면, 데이터가 바뀜을 알려준다.
    func tableView(_ tableView: UITableView, commit edittingStyle:
                    UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath){
        if edittingStyle == .delete {
            let asset: PHAsset = self.fetchResult[indexPath.row]
            
            PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.deleteAssets([asset] as NSArray)
            }, completionHandler: nil)
        }
    }
    
    // 포토라이브러리가 바뀌면 호출되는 메서드 
    func photoLibraryDidChange(_ changeInstance: PHChange) {
        guard let changes = changeInstance.changeDetails(for: fetchResult)
        else{ return }
        
        fetchResult = changes.fetchResultAfterChanges
        
        OperationQueue.main.addOperation {
            self.tableView.reloadSections(IndexSet(0...0), with: .automatic)
        }
    }
반응형

'iOS > storyboard & code' 카테고리의 다른 글

Stack View  (0) 2021.12.27
액션시트 / 얼럿  (0) 2021.12.27
세그(Segue) / 화면전환  (0) 2021.12.23
TableVIew / custom  (0) 2021.12.21
테이블뷰 / DataSource와 Delegate  (0) 2021.12.21
Comments