简体   繁体   English

UIImagePicker收到称为viewDidLoad的内存警告,并清除UITextField

[英]UIImagePicker received memory warning called viewDidLoad and clears UITextField

I am displaying a UIImagePicker from my UIViewController , in my UIViewController I have a few UITextField . 我从我的UIViewController显示一个UIImagePicker ,在我的UIViewController我有一些UITextField

Now a user has filled out some values in this UITextField and then he selects an image from the UIImagePicker , after that it receives a memory warning, and calls viewDidLoad again, but then all the data that the user had entered in the UITextField is missing . 现在,用户已在此UITextField填写了一些值,然后他从UIImagePicker选择了一个图像,此后它收到内存警告,并再次调用viewDidLoad,但随后该用户在UITextField输入的所有数据都丢失了。 How do I deal with this? 我该如何处理?

Code: 码:

- (void) showImageSelector: (UITapGestureRecognizer *) tapGestureRecognizer
{
    UIActionSheet *actionSheet;
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        actionSheet = [[UIActionSheet alloc] initWithTitle:[PNRConstants kChoosePhoto] delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:[PNRConstants kPhotoLibrary], [PNRConstants kTakeAPicture], nil];
    }
    else{
        actionSheet = [[UIActionSheet alloc] initWithTitle:[PNRConstants kChoosePhoto] delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:[PNRConstants kPhotoLibrary], nil];
    }
    [actionSheet showInView:self.view.window];
}

#pragma -
#pragma UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex != actionSheet.cancelButtonIndex) {
        UIImagePickerController *controller = [[UIImagePickerController alloc] init];
        controller.delegate = self;
        controller.allowsEditing = YES;
        if (buttonIndex == 0) {
            // Photo Library
            controller.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        }
        else {
            // Camera
            controller.sourceType = UIImagePickerControllerSourceTypeCamera;
        }
        [self presentViewController:controller animated:YES completion:nil];
    }
}

When there is low memory and view controller's views are not needed, the views are unloaded from the memory. 当内存不足并且不需要视图控制器的视图时,将从内存中卸载视图。 (This however isn't the case from iOS 6.0, as views are no longer purged from the memory). (但是,iOS 6.0并非如此,因为视图不再从内存中清除)。

So when you receive memory warning, the views are unloaded from the memory. 因此,当您收到内存警告时,视图将从内存中卸载。 When you get back to it, the view controller's view is requested again and hence it is created/loaded again. 当您回到视图时,将再次请求视图控制器的视图,因此将再次创建/加载它。 Thus, you get viewDidLoad called again. 因此,您再次调用了viewDidLoad

At this time, this is all new fresh view that got loaded. 目前,这是所有已加载的新视图。 It has lost all it's previous properties. 它已经失去了以前的所有属性。

In order to avoid this, what you can do is - when user had set text field's properties (it's text most probably), you must have hold these values somewhere in variables, etc. 为了避免这种情况,您可以做的是-当用户设置了文本字段的属性(最有可能是文本)时,必须将这些值保存在变量中的某个位置,等等。

So, In your viewDidLoad , check if that variable exists and/or holds any values. 因此,在您的viewDidLoad ,检查该变量是否存在和/或保留任何值。 If it doesn't, it means it's the very first time view has loaded. 如果没有,则意味着它是第一次加载视图。 Here, you do nothing. 在这里,您什么都不做。

However, once user set's some text in to the text field, the controller's view gets unloaded, it gets loaded again later, it's viewDidLoad gets called. 但是,一旦用户在文本字段中输入了一些文本,就会卸载控制器的视图,稍后再加载它,调用viewDidLoad Here, at this time the variable holds the text value that was entered earlier. 在这里,此时变量保存了之前输入的文本值。 So set the set of the textField. 因此,设置textField的集合。

In short, the code would look something like this: 简而言之,代码如下所示:

-(void) viewDidLoad {
    [super viewDidLoad];

    if (yourVariableHoldingTextInput) {
        // Variable holding the text field's input exists. This means user had set some input to the text field. View was purged from memory and is now loaded again.
        yourTextField.text = yourVariableHoldingTextInput; // Essentially, set the text field's text with the variable's value.
    }else {
        // Here we do nothing. This clearly means the controller's view loaded very first time.
    }
}

UIImagePicker consumes more memory from processor.. So you need to solve first this Memory Warning. UIImagePicker从处理器消耗更多的内存。因此,您需要首先解决此内存警告。

I got same kind of issue when i was using camera and photo library for Video. 当我将摄像机和照片库用于视频时,我遇到同样的问题。

After i tricks used and it solved. 经过我的技巧,它解决了。 Here are the tricks 这是窍门

Globally define UIImagePickerController and access 全局定义UIImagePickerController和访问

And here i have use code to call library 在这里我有使用代码来调用库

-(UIImagePickerController *)getImagePickerController{
    if (!imagePickerController) {
        imagePickerController = [[UIImagePickerController alloc]init];
    }
    return imagePickerController;
}

After call this UIImagePicker instance to videoPicker 将此UIImagePicker实例调用后,将其设置为videoPicker

videoPicker = [self getImagePickerController]; 
    videoPicker = [[UIImagePickerController alloc] init];
    videoPicker.sourceType =  UIImagePickerControllerSourceTypePhotoLibrary;
    videoPicker.delegate = self;
    videoPicker.allowsEditing = YES;
    videoPicker.mediaTypes =  [NSArray arrayWithObject:(NSString *)kUTTypeMovie];    
    videoPicker.videoQuality = UIImagePickerControllerQualityTypeHigh;
    videoPicker.videoMaximumDuration = 30.0;
    NSArray *sourceTypes = [UIImagePickerController availableMediaTypesForSourceType:videoPicker.sourceType];
    if (![sourceTypes containsObject:(NSString *)kUTTypeMovie ])
    {
        NSLog(@"no video");
    }
    else
    {
        [self presentModalViewController:videoPicker animated:YES];
    }

After cancel or select any media dismiss Picker only and release. 取消或选择任何媒体后,仅关闭Picker并释放。 Dont release and dismiss do with videoPicker . 不要释放和关闭videoPicker

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{   
    [picker dismissModalViewControllerAnimated:YES];
}

And if already picker instance is there than dont alloc once again. 如果已经存在选择器实例,则不要再分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM