0

我正在编写的应用程序的这一部分遇到了很多问题,我相信这里的人们已经厌倦了我,所以我将尝试在这篇文章中解决我的所有问题。我正在开发一个类似于照片库的应用程序,并且我正在实现让用户从他们的画廊中删除照片的选项。为此,我决定在每张图片上放置一个隐形按钮。当用户点击“编辑”按钮时,每张图片上隐藏的删除按钮将变为活动状态。为了简单起见,我在每个隐藏按钮上都使用了相同的 IBOutlet,并且我在 Interface Builder 中适当地标记了每个按钮。当用户点击图片上的按钮时,会出现一个警告视图,询问他们是否真的要删除它。如果他们点击是,我调用 removeObjectAtIndex 并从 UI 中删除图像。但是,当我在警报视图中单击“是”时,我从 Xcode 中收到一条错误消息:

2012-04-04 11:26:40.484 AppName[608:f803]-[UIButton setImage:]:无法识别的选择器发送到实例 0x6a922c0

2012-04-04 11:26:40.485 应用名称[608:f803]由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[UIButton setImage:]:无法识别的选择器发送到实例 0x6a922c0” *

几个小时以来,我一直试图弄清楚是什么原因造成的,但无济于事。我没有在代码中的任何位置设置 UIButton 的图像。我在 IB 中做过,但我只是将按钮类型设置为自定义,以便它们看起来不可见。我将在下面发布我的整个文件,我在我的代码中找不到任何问题,因此非常感谢任何帮助!谢谢。 编辑这是代码的当前版本:

    - (IBAction)grabImage {
    self.imgPicker = [[UIImagePickerController alloc] init];
    self.imgPicker.delegate = self;
    self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        _popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
        [_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    } 

    else {
        [self presentModalViewController:imgPicker animated:YES];
    }
    [self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
    if (imageView.image == nil) {
        imageView.image = img;

        self.array = [NSMutableArray arrayWithObject:[NSData dataWithData:UIImagePNGRepresentation(imageView.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;

    }

    if (imageView2.image == nil) {
        imageView2.image = img;
        NSLog(@"The image is a %@", imageView);
        [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView2.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }

    if (imageView3.image == nil) {
        imageView3.image = img;

        [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView3.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }

    if (imageView4.image == nil) {
        imageView4.image = img;

        [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView4.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
}
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Photo Gallery", @"Photo Gallery");
        self.tabBarItem.image = [UIImage imageNamed:@"42-photos.png"];
    }
    return self;
}
////start of saving////


- (void)applicationDidEnterBackground:(UIApplication*)application {
    NSLog(@"Image on didenterbackground: %@", imageView);
    self.array = [NSMutableArray arrayWithObject:[NSData dataWithData:UIImagePNGRepresentation(imageView.image)]];

    [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView2.image)]];
     [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView3.image)]];
      [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView4.image)]];

            [self.user setObject:self.array forKey:@"images"];
    [user synchronize];

            }

- (void)viewDidLoad
    {
        self.user = [NSUserDefaults standardUserDefaults];
        NSLog(@"It is %@", self.user);
        self.array = [[self.user objectForKey:@"images"]mutableCopy];
        imageView.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:0]];
        imageView2.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:1]];
        imageView3.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:2]];
        imageView4.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:3]];



        UIApplication *app = [UIApplication sharedApplication];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidEnterBackground:)
                                                     name:UIApplicationDidEnterBackgroundNotification
                                                   object:app];

        backToGalleryButton.hidden = YES;
        tapToDeleteLabel.hidden = YES;
        deleteButton1.hidden = YES;
        [super viewDidLoad];

    }




///// shows the hidden and invisible "delete" button over each photo.
- (IBAction)editButtonPressed:(id)sender {
    grabButton.hidden = YES;
    editButton.hidden = YES;
    backToGalleryButton.hidden = NO;
    tapToDeleteLabel.hidden = NO;
    deleteButton1.hidden = NO;
}
////

// This is when the user taps on the image to delete it.
- (IBAction)deleteButtonPressed:(id)sender {
    NSLog(@"Sender is %@", sender);
    UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:@"Delete"
                                                              message:@"Are you sure you want to delete this photo?"
                                                             delegate:self
                                                    cancelButtonTitle:@"No"
                                                    otherButtonTitles:@"Yes", nil];
    [deleteAlertView show];
    int imageIndex = ((UIButton *)sender).tag;
    deleteAlertView.tag = imageIndex;

}

- (void)alertView: (UIAlertView *) alertView 
clickedButtonAtIndex: (NSInteger) buttonIndex
{


    if (buttonIndex != [alertView cancelButtonIndex]) {
        NSLog(@"User Clicked Yes. Deleting index %d of %d", alertView.tag, [array count]);
        NSLog(@"The tag is %i", alertView.tag);
        [self.array removeObjectAtIndex: alertView.tag];
        NSLog(@"After deleting item, array count  = %d", [array count]);
    NSLog(@"Returned view is :%@, in view: %@", [self.view viewWithTag:alertView.tag], self.view);
        ((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
    }

    [self.user setObject:self.array forKey:@"images"];
}

更新:我添加了断点,发现那((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;是导致崩溃的行,但我仍然不知道为什么。

4

2 回答 2

2

我没有看到setImage:在您粘贴到问题中的任何代码中被调用,但我可以告诉您: UIButtonsetImage方法实际上需要按钮状态作为第二个参数。

例如

[UIButton setImage: forState:]

我已经为您链接了 Apple 的文档。

如果您的调用setImage:没有第二个参数,那将解释您看到的“无法识别的选择器错误”。

于 2012-04-04T17:42:09.637 回答
1

这是@MichaelDautermann 的扩展,他很好地指出 UIButton 有一个 setImage:forState: 方法,但没有 setImage 方法。但是,您正在调用 set image。不是在按钮上,而是当您说 imageView.image 和 imageView2.image 时。这会调用图像视图的 setter 方法。我会设置一个断点(或使用 NSLog 和 %@ 项)以确保 imageView 实际上是一个 imageView 而不是一个按钮。如果它以某种方式从你下面改变,这可能是导致问题的原因。只需在这两行处设置一个断点,看看你是否能越过它们。

此外,如果 Xcode 没有将您弹出到实际导致问题的行,请检查您的崩溃日志。符号化的,日志会给你行号。或者,一种不太直接的方法是在您在答案中提供的方法的末尾设置断点,并查看您通过了多少。一旦你崩溃了,你可以缩小导致你悲伤的方法,然后开始在方法中设置断点,直到你到达有问题的行。

更新: 您在评论中说 ((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil 是您所拥有的,但 self.view 是 UIControl。更改演员表不会影响结果。您尝试删除 UIControl 子视图的 UIImageView 是其图像吗?如果没有,您将永远无法从 viewWithTag 取回图像视图。通常,self.view 指的是视图控制器的视图,所以如果你得到一个 UIControl,我的假设是你的整个视图是一个 UIControl,或者你在错误的类中这样做。你在哪个类做这个,它是什么的子类?看来您是在视图控制器中执行此操作,但我只是想确定一下。同样,在任何一种情况下(UIControl 或 UIImageView),两个类都没有响应 setImage。

于 2012-04-04T18:14:09.350 回答