0
votes

I have a "profile header" view, with 2 different UIImageView, and 2 UIButton - one button for each image view. And I'm using a protocol to delegate the Target/selector of each button to my controller.

On my controller:

// my image picker
private let profileImagePicker = UIImagePickerController()

// Set's the profile image and Cover pic
private var selectedProfilePic: UIImage? {
    didSet {
        headerView.profileImageView.image = selectedProfilePic
    }
}
private var selectedCoverPic: UIImage? {
    didSet {
        headerView.profileCover.image = selectedCoverPic
    }
}

On this controller, I also have 2 functions for each button present on my view. One for my profile pic button, another to Cover pic button. Both presents the image Picker

func ChangeCoverPhoto(){
    present(profileImagePicker, animated: true, completion: nil)
}

func ChangeProfilePhoto(){
    present(profileImagePicker, animated: true, completion: nil)
}

Then I have the extension for UIImagePickerControllerDelegate

func imagePickerController(_ picker: UIImagePickerController, 
     didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    
     guard let image = info[.editedImage] as? UIImage else { return }

     // ** here my Problem begin **
     selectedProfilePic = image
}

How can I Set the selected image from the imagepicker on the selectedProfilePic OR selectedCoverPic based on the corresponding function trigged by the buttons via protocol?

1

1 Answers

0
votes

You can create an enum for picker mode and check it when assigning the picked photo to its related property. - unknown case is optional.

private enum ImagePickerMode {
    case coverPhoto
    case profilePhoto
    case unknown
}

By keeping it on the related controller as a variable, you can check which photo property should be updated.

private var imagePickerMode: ImagePickerMode = .unknown

If you change the method for changing photo as following, you may reduce the duplicate code.

private func changePhoto(for mode: ImagePickerMode){
    imagePickerMode = mode
    present(profileImagePicker, animated: true, completion: nil)
}

If you are using addTarget method for the buttons instead of IBAction, you may choose to assign a tag value to the button to separate them.

This also requires you to update ImagePickerMode to include rawValues which corresponds to button tags. Default rawValue for integers start from 0 with increment of 1. You should update both ImagePickerMode and changePhoto as following:

private enum ImagePickerMode: Int {
    case coverPhoto
    case profilePhoto
    case unknown
}

private func changePhoto(for sender: UIButton) {
    imagePickerMode = ImagePickerMode(rawValue: sender.tag) ?? .unknown
    present(profileImagePicker, animated: true, completion: nil)
}

Eventually, delegate method becomes:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    guard let image = info[.editedImage] as? UIImage else { return }

    switch imagePickerMode {
        // handle cases and assign related image here!
    }
}