I am working on a simple universal ios app that displays images in a table, when the user selects an image it goes to a detail view which includes a larger view of the image and a UIButton/IBAction to save the image to their photo album.. I use the following code which for the most part works great, except the very first time the user presses "save" it hangs with a loooooong lag, a good 5-6sec. If the user hits it multiple times during the lag time then the image gets saved multiple times, even if I include code to disable the button for a few seconds. The highlighted button also will not show during the first touch of the button. Thereafter it works fine. Does anyone know the reason for the lag and how to fix it. Thanks!
-(IBAction)saveBtn:(UIButton *)pressed{
UIImageWriteToSavedPhotosAlbum(image.myimage, self, #selector(imageSavedToPhotosAlbum: didFinishSavingWithError: contextInfo:), nil);
}
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
NSString *message;
NSString *title;
if (!error) {
title = NSLocalizedString(#"Image Saved", #"");
message = NSLocalizedString(#"You can now view the image in your photo album", #"");
} else {
title = NSLocalizedString(#"Save Failed", #"");
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil];
[alert show];
[alert release];
}
The problem was unrelated to this code, and was instead due to memory usage with large image files in the table view.
Related
I want to take picture with AVCaptureSession for iOS, I can take a picture but it takes like a print screen and save it on PhotoLibrary, How can I get real picture not print screen and also save it on view not in a library, would you please help me in this implementation,
Thanks in advance!
Here is my code:
CGImageRef UIGetScreenImage(void);
- (void) scanButtonPressed {
CGImageRef screen = UIGetScreenImage();(what should I use here instead of
UIGetScreenImage)
UIImage* image = [UIImage imageWithCGImage:screen];
CGImageRelease(screen);
// Save the captured image to photo album
UIImageWriteToSavedPhotosAlbum(image, self,
#selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void
*)contextInfo
{
UIAlertView *alert;
if (error)
alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Unable to save image to Photo Album."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
else {
CoverCapturePhoto *c = [[CoverCapturePhoto alloc] init];
[self.navigationController pushViewController:c animated:YES];
[c.captureImage setImage:image];
}
[alert show];
}
You need to investigate and use AVCaptureStillImageOutput. Apple supplies documentation showing how to take an image with the camera.
You are explicitly saving the image with UIImageWriteToSavedPhotosAlbum - you don't need to do that. Just use the image in an image view or similar.
Or if I misunderstood, see How to take a screenshot programmatically.
In my application when a user clicks on the save button in the toolbar, the user is then prompted through UIAlertView for which way they would like to save their current work by choosing either to save as an image or save as a play. When the user selects save as a play they are then prompted with a 2nd UIAlertView which also has a text field for them to insert the name for the play. What I am trying to achieve is so that when no text is inputted, the Ok button is disabled and when the length of the text typed in is 1 or more, the file is then able to be saved (using archiver, this works correctly so this is not an isue) and the Ok button is then enabled. Listed below is the code that shows the two alert views, as well as what happens when different items from the views are selected.
- (IBAction)selectSaveType {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#""
message:#"Please Select an Option."
delegate:self
cancelButtonTitle:#"Save Play"
otherButtonTitles:#"Save to Photos", nil];
[message show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Save Play"])
{
NSLog(#"Save Play was selected.");
[self GetFileName];
}
else if([title isEqualToString:#"Save to Photos"])
{
NSLog(#"Save To Photos was selected.");
//here is where we need to find how to call saveDrawing.
[self saveDrawing];
}
else if([title isEqualToString:#"Ok"])
{
NSLog(#"OK selected");
UITextField *fName= [alertView textFieldAtIndex:0];
NSString *NameFile = fName.text;
[self savePlay:NameFile];
}
}
-(void)savePlay:(NSMutableString *)fileName{
//code here to save via archive.
NSArray *pathforsave = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [pathforsave objectAtIndex:0];
//here we need to add the file extension onto the file name before we add the name to the path
[fileName appendString:#".hmat"];
NSString *strFile = [documentDirectory stringByAppendingPathComponent:fileName];
[NSKeyedArchiver archiveRootObject:matView.drawables toFile:strFile];
}
I have been trying to use the following code below to handle this, but when the first UIAlertView fires (which is the asking to select a play - no text field present) - the function below then is ran and crashes the application since there are no text fields in the first alert view.
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
NSString *inputText = [[alertView textFieldAtIndex:0] text];
if( [inputText length] >= 1 )
{
return YES;
}
else
{
return NO;
}
}
alertViewShouldEnableFirstOtherButton is being hit when the first alert fires, then my application crashes in the simulator. Does anyone see why this would happen? Two things I am not so sure of
One - why the handle for the Ok button on the 2nd alert view to name the play is handled in the same block where the other buttons are handled. Since its a separate alert view, shouldn't it be in its own block?
Two - why alertViewShouldEnableFirstOtherButton is hit when it hasn't gotten to the 2nd alert view yet, it is called and runs with the first alert view, which crashes the app.
Thanks for your help, I am new to objective C.
Delegate methods for an alert view will be called for any alert view you present. That being said this code will crash because textFieldAtIndex:0 does not exist on a plain alert view. To solve this all you need to do is add an if statement to the delegate method identifying which alert called the action.
Edit: No longer identifies alert by name. Code now checks the style of the delegates sender.
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView
{
if (alertView.alertViewStyle == UIAlertViewStylePlainTextInput) {
if([[[alertView textFieldAtIndex:0] text] length] >= 1 )
{
return YES;
}
else
{
return NO;
}
}else{
return YES;
}
}
I have a UIAlertView that asks a user whether they want to copy a bunch of contacts. After the user clicks "Continue," I want the AlertView to disappear to be replaced by a UIProgressView that shows the rate of loading.
Everything functions properly except that the alert remains on the XIB after the user clicks Continue, and it doesn't disappear until the entire process has run. As soon as it disappears, the UIProgressView bar appears but by then it has reached 100%.
How do I clear the UIAlertView off the screen immediately and show the progress bar growing instead.
Here's the code. Thanks for help.
-(IBAction)importAllAddressBook:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Import ALL Contacts" message:#"Do you want to import all your Address Book contacts? (Please note that only those with a first and last name will be transfered)" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Continue", nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0) {
NSLog(#"NO STOP");
return;
}else {
NSLog(#"YES CONTINUE");
importAllContactsProgress.hidden = NO; // show progress bar at 0
[self importAllMethod];
}
}
// method to import all Address Book
-(void) importAllMethod {
importAllContactsProgress.progress = 0.0;
load names etc etc
You'll want to perform the perform the import on a background thread:
[self performSelectorInBackground:#selector(importAllMethod)];
Your import method is blocking the main thread and preventing any UI actions from occurring.
Can someone help me with implementing this code into a view based app?
This is the code that I have:
- (void)webViewUIWebView *)newsweb didFailLoadWithErrorNSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Error1!" message:#"Please confirm network connectivity and try again!" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alert show];
[alert release];
}
With this code and any other code that I may need, but don't know, I would like to know what code to implement into the .h + .m view controller files.
What I am trying to achieve is an error after starting the app if there is no network connection available. What I'm worried about also but not quite sure if it will happen, is that this will repeat the error "x" times for how many UIViews I have. If that would be the case could you also help me should that it would only show the error once.
Put a Boolean in your header file, and when the alert fires, change it. If the Boolean is false, then simply don't show the alert.
#interface
BOOL alertShown;
#end
#implementation
-(void)applicationDidFinishLaunching{
alertShown = NO;
}
-(void)webViewError{
if(alertShown == NO){
//show the alert
alertShown = YES;
}
}
#end
I'm really new at this. I've been working my way through a couple of "HelloWorld" type tutorials that basically have a text field, a button, and when you click the button it alerts whatever's in the text field. I've gotten as far as getting an alert to show and being able to set the title, message, and button text directly. However my attempts at getting the contents of my UITextField keep failing. I either get errors, no response, or just "(null)". My code's here.
#synthesize textField;
- (IBAction)btnClicked:(id)sender {
//text of textField
NSString *str = [[NSString alloc] initWithFormat:#"Hello, %#", textField.text];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello!"
message:str delegate:self
cancelButtonTitle:#"Done"
otherButtonTitles:nil];
[alert show];
[alert autorelease];
}
It looks like the textField property is not properly linked to the UITextField object you have in interface builder. Make sure your IBOutlets are set correctly.