Ch.15 Silver: Removing an Image
# 이미지 삭제 버튼
-
아이템의 이미지를 삭제할 수 있는 버튼 추가하기
-
버튼이라고 하기는 했는데 버튼 버전도 하고 이미지를 꾹 눌렀을 때 삭제 옵션이 뜨는 방식으로도 했다...
# 삭제 버튼
- 스토리보드에서 버튼을 하나 추가하고 deleteImage(_:) action method 에서 imageStore.deleteImage(forKey:) 메서드를 호출해서 이미지를 삭제했다. 이렇게 하면 삭제는 되는데 뷰는 바로 업데이트 되지 않고 사진이 계속 남아있어서 imageView.image = nil 로 설정해서 사라지도록 했다.
class DetailViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
...
@IBOutlet var imageDeleteButton: UIButton!
@IBAction func deleteImage(_ sender: UIButton) {
imageStore.deleteImage(forKey: item.itemKey)
imageView.image = nil
imageDeleteButton.isEnabled = false
}
}
- 이미지가 있을 때만 버튼을 활성화하고 싶어서
1) 뷰가 나타날 때
2) 이미지를 선택했을 때
3) 이미지를 삭제할 때
각각 버튼의 상태를 상황에 맞게 업데이트하도록 했다.
class DetailViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
nameField.text = item.name
serialNumberField.text = item.serialNumber
valueField.text = numberFormatter.string(from: NSNumber(value: item.valueInDollars))
dateLabel.text = dateFormatter.string(from: item.dateCreated)
let key = item.itemKey
let imageToDisplay = imageStore.image(forKey: key)
imageView.image = imageToDisplay
if imageToDisplay == nil {
imageDeleteButton.isEnabled = false // 버튼 비활성화
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[.originalImage] as! UIImage
imageStore.setImage(image, forKey: item.itemKey)
imageView.image = image
imageDeleteButton.isEnabled = true // 버튼 활성화
dismiss(animated: true)
}
@IBAction func deleteImage(_ sender: UIButton) {
imageStore.deleteImage(forKey: item.itemKey)
imageView.image = nil
imageDeleteButton.isEnabled = false // 버튼 비활성화
}
}
# 이미지를 꾹 누르면 삭제 버튼 뜨게 하기
-
해볼까 말까 고민했지만...연습 겸 해봤다..
-
일단 스토리보드에서 UIImageView 에 Long Press Gesture Recognizer 를 추가한 다음, UIImageView 는 유저 이벤트에 반응하지 않는 게 디폴트이므로 isUserInteractionEnabled 프로퍼티를 true 로 바꿔줘서 이미지를 꾹 눌렀을 때 반응할 수 있도록 했다.
class DetailViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
nameField.text = item.name
serialNumberField.text = item.serialNumber
valueField.text = numberFormatter.string(from: NSNumber(value: item.valueInDollars))
dateLabel.text = dateFormatter.string(from: item.dateCreated)
imageView.isUserInteractionEnabled = true // 유저 이벤트 허용!
let key = item.itemKey
let imageToDisplay = imageStore.image(forKey: key)
imageView.image = imageToDisplay
}
}
-
그 다음에 imageLongPressed action method 를 추가하고, 이미지가 있는 경우에만 presentDeleteImageActionSheet() 메서드를 호출하도록 했다.
-
presentDeleteImageActionSheet() 에서는 UIAlertController 를 커스텀해서 삭제 버튼을 띄울 수 있도록 했고, 삭제 버튼을 누르는 경우에 삭제 작업은 아까와 마찬가지로 imageStore.deleteImage(forKey:) 메서드를 호출하고 imageView.image = nil 로 설정해줬다.
class DetailViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@IBAction func imageLongPressed(_ sender: UILongPressGestureRecognizer) {
if imageView.image != nil {
presentDeleteImageActionSheet()
}
}
private func presentDeleteImageActionSheet() {
let alertController = UIAlertController(title: nil,
message: nil,
preferredStyle: .actionSheet)
alertController.modalPresentationStyle = .popover
alertController.popoverPresentationController?.sourceView = imageView
alertController.popoverPresentationController?.sourceRect = imageView.frame
let deleteAction = UIAlertAction(title: "Delete Image",
style: .destructive) { _ in
self.imageView.image = nil
self.imageStore.deleteImage(forKey: self.item.itemKey)
}
alertController.addAction(deleteAction)
let cancelAction = UIAlertAction(title: "Cancel",
style: .cancel,
handler: nil)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
}
아이패드에서 popover anchor 를 이미지에 딱 맞게 설정하고 싶었는데 해보다가 잘 안돼서 일단 포기...하려고 했는데 내가 공식 문서를 제대로 안봐서 생긴 문제였다. popover 의 anchor 를 설정할 때는
1) barButtonItem 프로퍼티를 설정
2) sourceView 프로퍼티 그리고 sourceRect 프로퍼티를 설정
하는 두 가지 방법이 있는데 나는 sourceView 만 설정하고 sourceRect 는 설정하지 않아서 popover 의 위치가 이상해진 거였다....alertController.popoverPresentationController?.sourceRect = imageView.frame
를 추가해줬더니 위치가 잘 조정됐다!
- sourceRect 에 super view 에서의 imageView 의 위치와 크기를 넘기는 게 맞다고 생각해서 frame 으로 넘겼는데, 궁금해서 bounds 로도 해봤더니 위치가 다시 이상하게 나왔다...frame 이 맞는 접근인 거 같다!
- sourceRect 에 super view 에서의 imageView 의 위치와 크기를 넘기는 게 맞다고 생각해서 frame 으로 넘겼는데, 궁금해서 bounds 로도 해봤더니 위치가 다시 이상하게 나왔다...frame 이 맞는 접근인 거 같다!
Author And Source
이 문제에 관하여(Ch.15 Silver: Removing an Image), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sunnysideup/Ch.15-Silver-Removing-an-Image저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)