아이템의 이미지를 삭제할 수 있는 버튼 추가하기
버튼이라고 하기는 했는데 버튼 버전도 하고 이미지를 꾹 눌렀을 때 삭제 옵션이 뜨는 방식으로도 했다...
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
}
}
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)
}
}
alertController.popoverPresentationController?.sourceRect = imageView.frame
를 추가해줬더니 위치가 잘 조정됐다!