首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS 在 UIImagePickerController 代理中獲取觸發按鈕引用

     編輯:程式設計綜合問答

UIImagePickerController 的代理方法 didFinishPickingMediaWithInfo: 不直接傳遞觸發按鈕 (sender),需通過成員變量保存引用或Tag 查找間接獲取。

方案一:成員變量保存 Sender(推薦)

@interface ViewController ()
@property (nonatomic, weak) UIButton *lastTappedButton; // 弱引用避免循環保留
@end

@implementation ViewController

- (IBAction)selectImageTapped:(UIButton *)sender {
    self.lastTappedButton = sender; // 保存引用
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    [self presentViewController:picker animated:YES completion:nil];
}

- (void)imagePickerController:(UIImagePickerController *)picker 
        didFinishPickingMediaWithInfo:(NSDictionary *)info {
    // 這裡可以直接使用 self.lastTappedButton
    UIButton *triggerButton = self.lastTappedButton;
    // 例如:設置按鈕圖片為選中的照片
    UIImage *selectedImage = info[UIImagePickerControllerInfoKeyOriginalImage];
    [triggerButton setImage:selectedImage forState:UIControlStateNormal];
    
    [picker dismissViewControllerAnimated:YES completion:nil];
    self.lastTappedButton = nil; // 用完釋放
}
@end

方案二:使用 Tag + viewWithTag:(不推薦,易出錯)

// 設置按鈕 Tag
button.tag = 1001;

// 代理中查找
- (void)imagePickerController:(UIImagePickerController *)picker 
        didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIButton *btn = (UIButton *)[self.view viewWithTag:1001];
    // 風險:Tag 可能衝突、view 層級變化導致找不到
}

方案三:自定義 Picker 子類傳遞 Sender(進階)

@interface CustomImagePicker : UIImagePickerController
@property (nonatomic, weak) UIView *sourceView; // 或 UIButton *sourceButton
@end

// 使用時
CustomImagePicker *picker = [[CustomImagePicker alloc] init];
picker.sourceView = sender;
// 代理中強轉獲取
CustomImagePicker *customPicker = (CustomImagePicker *)picker;
UIButton *btn = (UIButton *)customPicker.sourceView;

最佳實踐總結

  1. 成員變量法最簡潔安全:弱引用、用完即釋、無 Tag 衝突風險。
  2. 若有多個入口(相機/相冊/拍照),可用 enum 標記來源類型,配合 sender 統一處理。
  3. iOS 11+ 建議使用 PHPickerViewController (PhotosUI) 替代 UIImagePickerController,支援多選、隱私權限更友好。

核心原則:代理方法不傳 sender 時,由調用方在發起前保存上下文,這是 Cocoa Touch 設計模式的常見慣例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved