UIImagePicker set more than one image view - ios

I have several buttons. When either of the buttons are pressed it pops up and alertView asking the user to take a photo or select from the camera roll. Now the issue I am having is that I have 12 buttons and 12 UIImageViews. All buttons have there own action which pops the alert and allows the user to choose either of the options. Now in didFinishPickingMediaWithInfo method I pass the image from the camera or the camera roll to the first imageView. This all works fine, however if I want to select button 2 which fires the another alert with another tag i want to set imageView 2 and so on so on (Not replace imageView1). I need a way to distinguish in the didFinishPickingMediaWithInfo what imageView to set based on the button selection which popped the alert. Because at the moment the first image view is only getting set and reset if I choose another button which should set the corresponding image.
Heres the action for the button.
-(IBAction) addPhoto1:(id) sender {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Image Source" message:#"Take a photo or select a previously taken photo" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Take Photo", #"Select Photo", nil];
[alert show];
alert.tag = 101;
[alert release];
}
And alert clickedButtonAtIndex:
- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alert.tag == 101) {
if (buttonIndex == 1) {
//Take photo
[self performSelector:#selector(takePicture:) withObject:nil afterDelay:0.0];
}
else if (buttonIndex == 2){
//Camera roll
[self performSelector:#selector(pictureAlbum:) withObject:nil afterDelay:0.0];
}
else if (buttonIndex == 0) {
NSLog(#"Cancel");
}
}
}
And here's the didFinishPickingMediaWithInfo:
-(void) imagePickerController:(UIImagePickerController *) picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:dict completionBlock:nil];
if (addFirstImage.tag == 1001) {
firstImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
firstImage.layer.cornerRadius = 5;
firstImage.layer.masksToBounds = YES;
}
if (addSecondImage.tag == 1002) {
secondImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
secondImage.layer.cornerRadius = 5;
secondImage.layer.masksToBounds = YES;
}
}
}
Now obviously this is not right whats the best way to set the correct imageViews image based on the button from the Alert that was originally pressed? (addFirstImage and addSecondImage are both buttons linked via IB)
Many thanks

Why don't you use action's `sender' to 'remembers' which Button was pressed first ?
Using IBOutletCollections, ordered with same indexes :
#property (...) IBOutletCollection(UIButton) allYourButtons;
#property (...) IBOutletCollection(UIImageView) allYourImageViews;
// I suppose that both Collections objects have 'tags' (set in XIB file)
// a UIButton and the corresponding UIImageVIew have the SAME tag
#property (...) NSInteger clickedButtonIndex;
- (IBAction) imageViewWasPressed:(id)sender
{
//keep a reference to the specific button that launched the action
self.clickedButtonIndex = [(UIButton *)sender tag];
[self presentAlertViewForPictureChoice];
}
Then, you use clickedButtonIndex in your UIAlertView delegate method to find which UIImageVIew from allYourImageViews should have its image updated...
- (UIImageView *)imageToUpdateForSelectedIndex:(NSInteger)anIndex
{
UIImageView *result = nil;
for (UIImageView *imageView in self.allYourImageViews){
if(imageView.tag == anIndex){
result = imageView;
break;
}
}
return result;
}
(EDIT)
Ok, another way to associate a UIButton with a UIImageView is to create a subclass
// a new UIButton subclass
ButtonWithImageView : UIButton
#property (...) IBOutlet UIImageView *relatedImageView;
//IBOutlet enables you to directly link a Button with its imageVIew in your XIB
// in your controller
#property (...) ButtonWithImageView *selectedButton;
- (IBAction)buttonWasPressed:(id)sender
{
...
self.selectedButton = (ButtonWithImageView *)sender;
}
Then all you have to do is edit self.selectedButton.relatedImageView

Ok I figured out how to do this. Firstly I created an ivar int called myTag in interface file
int myTag;
I then tagged all my buttons with tag number i.e button1.tag = 1001 (to 1012 for my 12 buttons) in viewDidLoad,
I then created the one Action as opposed to 12 for each button. And connect all to this one action via IB.
- (IBAction)takePhoto:(UIButton*)sender {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Image Source" message:#"Take a photo or select a previously taken photo" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Take Photo", #"Select Photo", nil];
[alert show];
alert.tag = 101;
[alert release];
if (sender.tag == 1001){
NSLog(#"You clicked button 1");
myTag = 1001;
}
if (sender.tag == 1002){
NSLog(#"You clicked button 2");
myTag = 1002;
}
}
I then detect what button was pressed and pass an int value to myInt ivar
and then in my didFinishPickingMediaWithInfo I do this!
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:[image CGImage] metadata:dict completionBlock:nil];
if (myTag == 1001){
firstImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
firstImage.layer.cornerRadius = 5;
firstImage.layer.masksToBounds = YES;
}
if (myTag == 1002) {
secondImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
secondImage.layer.cornerRadius = 5;
secondImage.layer.masksToBounds = YES;
}
[picker dismissModalViewControllerAnimated:YES];
}
All working perfectly! Many thanks for your help though!

Related

Making a method save a UIImage to the photo library

I'm attempting to write an application that shows the camera feed, and you can take an image from it. I've successfully set up a UIButton and a linked action method (IBAction) but I'm having trouble making it trigger the UI to save the picture. I have it all set up so when everything goes correctly it should inform the user, but instead it crashes. Any insight would be greatly appreciated.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidBecomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)applicationDidBecomeActive
{
//Start the camera up
UIImagePickerController *imageViewPickerController = [[UIImagePickerController alloc] init];
//Hide default UI elements
imageViewPickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imageViewPickerController.showsCameraControls = NO;
imageViewPickerController.navigationBarHidden = YES;
imageViewPickerController.toolbarHidden = YES;
//Start the button overlay
UIView *btnView = [[UIView alloc] initWithFrame:imageViewPickerController.view.bounds];
btnView.opaque = NO;
btnView.clipsToBounds = YES;
//Start up the button
UIButton *snapButton = [[UIButton alloc] initWithFrame:CGRectMake(-6, 504, 65, 65)];
snapButton.alpha = 0.5;
snapButton.transform = CGAffineTransformMakeRotation(DEGREES_RADIANS(90));
[snapButton addTarget:snapButton action:#selector(takePhoto:) forControlEvents:UIControlEventTouchUpInside];
//Set the button's picture
UIImage *snapButtonImage = [UIImage imageNamed:#"Button.png"];
[snapButton setImage:snapButtonImage forState:UIControlStateNormal];
//Add button to the overlay
[btnView addSubview:snapButton];
//Overlay button view
imageViewPickerController.cameraOverlayView = btnView;
//Fix for iPhone 5 and make fullscreen
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, -55.0);
CGAffineTransform scale = CGAffineTransformMakeScale(1.333333, 1.333333);
CGAffineTransform rotate = CGAffineTransformMakeRotation(DEGREES_RADIANS(180));
CGAffineTransform transform = CGAffineTransformConcat(translate, scale);
transform = CGAffineTransformConcat(transform, rotate);
imageViewPickerController.cameraViewTransform = transform;
//Let's present it all
[self presentViewController:imageViewPickerController
animated:NO
completion:NULL];
}
- (IBAction)takePhoto:(id)sender {
[UIImagePickerController takePicture];
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Save image
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
UIAlertView *alert;
// Unable to save the image
if (error)
alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Unable to save image to Photo Album."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
else // All is well
alert = [[UIAlertView alloc] initWithTitle:#"Success"
message:#"Image saved to Photo Album."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
EDIT:
Revised code to resolve exception.
- (void)applicationDidBecomeActive
{
//Start the camera up
_imageViewPickerController = [[UIImagePickerController alloc] init];
//Hide default UI elements
_imageViewPickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
_imageViewPickerController.showsCameraControls = NO;
_imageViewPickerController.navigationBarHidden = YES;
_imageViewPickerController.toolbarHidden = YES;
//Start the button overlay
UIView *btnView = [[UIView alloc] initWithFrame:_imageViewPickerController.view.bounds];
btnView.opaque = NO;
btnView.clipsToBounds = YES;
//Start up the button
UIButton *snapButton = [[UIButton alloc] initWithFrame:CGRectMake(-6, 504, 65, 65)];
snapButton.alpha = 0.5;
snapButton.transform = CGAffineTransformMakeRotation(DEGREES_RADIANS(90));
[snapButton addTarget:snapButton action:#selector(snapThat) forControlEvents:UIControlEventTouchUpInside];
//Set the button's picture
UIImage *snapButtonImage = [UIImage imageNamed:#"Button.png"];
[snapButton setImage:snapButtonImage forState:UIControlStateNormal];
//Add button to the overlay
[btnView addSubview:snapButton];
//Overlay button view
_imageViewPickerController.cameraOverlayView = btnView;
//Fix for iPhone 5 and make fullscreen
CGAffineTransform translate = CGAffineTransformMakeTranslation(0.0, -55.0);
CGAffineTransform scale = CGAffineTransformMakeScale(1.333333, 1.333333);
CGAffineTransform rotate = CGAffineTransformMakeRotation(DEGREES_RADIANS(180));
CGAffineTransform transform = CGAffineTransformConcat(translate, scale);
transform = CGAffineTransformConcat(transform, rotate);
_imageViewPickerController.cameraViewTransform = transform;
//Let's present it all
[self presentViewController:_imageViewPickerController
animated:NO
completion:NULL];
}
- (void)snapThat {
[_imageViewPickerController takePicture];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
// Save image
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
UIAlertView *alert;
// Unable to save the image
if (error)
alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Unable to save image to Photo Album."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
else // All is well
alert = [[UIAlertView alloc] initWithTitle:#"Success"
message:#"Image saved to Photo Album."
delegate:self cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
}
EDIT 2: Including headers
#interface TurnikitViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
#property (strong, nonatomic) IBOutlet UIView *imageView;
#property (strong, nonatomic) UIImagePickerController *imageViewPickerController;
#end
You should have this as property:
#property (strong, nonatomic) UIImagePickerController *imageViewPickerController;
then you init that as you are doing:
_imageViewPickerController = [[UIImagePickerController alloc] init];
and when you save:
[_imageViewPickerController takePicture];
Instead now, you are not calling the method on the instance, but on the class..that is an error:
[UIImagePickerController takePicture];
And also, you are adding as target of your button, itself..instead the target is self:
[snapButton addTarget:self action:#selector(snapThat) forControlEvents:UIControlEventTouchUpInside];

Obj-C: Issue with object from block

Im pretty new in programming and im currently looking at blocks which im having some issues with. Im having a hard time reaching an object which is defined within my block. Actually I cannot really explain this issue in an accurate way, so ill give you some code and pictures, and hope that it makes sense and that you excuse my dodgy knowledge and try to help me understand the problem.
So Im starting off by running this block
- (void)fetchSite
{
//Initiate the request...
[[FeedStore sharedStore] fetchSites:^(RSSChannel *objSite, NSError *err) {
//When the request completes, this block will be called
if (!err) {
//If everything went ok, grab the object
channelSite = objSite;
//Now we need to extract the first siteId and give it to sharedstore
RSSItem *site = [[channelSite sites] objectAtIndex:0];
NSString *currentSiteId = [NSString stringWithFormat:#"%#", [site siteNumber]];
NSLog(#"DEBUG: LVC: fetchSite: currentSiteId: %#", currentSiteId);
[[FeedStore sharedStore] setCurrentSiteId:currentSiteId];
//Now we can call fetchEntries
[self fetchEntries];
} else {
//If things went bad, show an alart view
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Fel" message:#"Kunde inte bedömma din position relaterat till närmaste hållplats, försök gärna igen" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[av show];
//Stop UIRefreshControl
[refreshControl endRefreshing];
}
}];
}
Then fetchEntries is called:
- (void)fetchEntries
{
void (^completionBlock)(RSSChannel *obj, NSError *err) = ^(RSSChannel *obj, NSError *err) {
if (!err) {
//If everything went ok, grab the object, and reload the table and end refreshControl
channel = obj;
//Post notification to refreshTableView method which will reload tableViews data.
[[NSNotificationCenter defaultCenter] postNotificationName:#"RefreshTableView" object:nil];
//Stop UIRefreshControl
[refreshControl endRefreshing];
} else {
//If things went bad, show an alart view
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Fel" message:#"Kunde inte hämta avgångar för din hållplats, försök gärna igen" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[av show];
//Stop UIRefreshControl
[refreshControl endRefreshing];
}
};
//Initiate the request...
if (fetchType == ListViewControllerFetchBus) {
[[FeedStore sharedStore] fetchDepartures:completionBlock];
selectedSegment = 0;
} else {
[[FeedStore sharedStore] fetchDeparturesMetro:completionBlock];
selectedSegment = 1;
}
}
Reloading the table:
- (void)refreshTableView:(NSNotification *)notif
{
[[self tableView] reloadData];
}
Heres where I populate my custom table cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get received data from fetchEntries block
RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
//Get the new or recycled cell
ItemCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ItemCell"];
//Set the apperance
[[cell lineNumberLabel] setTextColor:[UIColor whiteColor]];
[[cell lineNumberLabel] minimumScaleFactor];
[[cell lineNumberLabel] setFont:[UIFont boldSystemFontOfSize:22]];
[[cell lineNumberLabel] adjustsFontSizeToFitWidth];
[[cell lineNumberLabel] setTextAlignment:NSTextAlignmentCenter];
[[cell destinationLabel] setTextColor:[UIColor whiteColor]];
[[cell displayTimeLabel] setTextColor:[UIColor whiteColor]];
[[cell displayTimeLabel] setTextAlignment:NSTextAlignmentLeft];
//Configure the cell with the item
if ([item lineNumber]) [[cell lineNumberLabel] setText:[item lineNumber]];
if ([item destination]) [[cell destinationLabel] setText:[item destination]];
if ([item displayTime]) [[cell displayTimeLabel] setText:[item displayTime]];
if ([item displayRow1]) [[cell destinationLabel] setText:[item displayRow1]];
return cell;
}
So when im running through these blocks in normal state everything works like a charm.
But the issues starts when Im calling fetchSite method from an UIActionSheet, or actually from an UISegmentedControl which is a subview of UIActionSheet, this takes place here:
- (void)displayPickerView
{
//First im creating an instance to PickerViewController which will handle the UIPickerView which is a subview of UIActionSheet. pickerArrayFromChannel holds entries for UIPickerView to show in its ViewController.
pickerViewController = [[PickerViewController alloc] init];
[pickerViewController initWithItems: pickerArrayFromChannel];
pickerViewController.delegate = self;
//initiate UIActionSheet which needs no delegate or appearance more than its style
actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:nil
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
//Create frame and initiate a UIPickerView with this. Set its delegate to the PickerViewController and set it to start at row 0
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.delegate = pickerViewController;
pickerView.dataSource = pickerViewController;
[pickerView selectRow:0 inComponent:0 animated:YES];
//Add this pickerView as subview to actionSheet
[actionSheet addSubview:pickerView];
//Now, create two buttons, closeButton and okButton. Which really are UISegmentedControls. Action to closeButton is (for now) dismissActionSheet which holds only following code " [actionSheet dismissWithClickedButtonIndex:0 animated:YES]; " and works fine
UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Stäng"]];
closeButton.momentary = YES;
closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
closeButton.tintColor = [UIColor blackColor];
[closeButton addTarget:self action:#selector(dismissActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:closeButton];
//OK button
UISegmentedControl *okButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Visa avgångar"]];
okButton.momentary = YES;
okButton.frame = CGRectMake(10, 7.0f, 100.0f, 30.0f);
okButton.segmentedControlStyle = UISegmentedControlStyleBar;
okButton.tintColor = [UIColor blueColor];
[okButton addTarget:self action:#selector(updateDeparturesFromActionSheet) forControlEvents:UIControlEventValueChanged];
[actionSheet addSubview:okButton];
//Now show actionSheet
[actionSheet showInView:[[UIApplication sharedApplication] keyWindow]];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
Now lets look at updateDeparturesFromActionSheet method and we're getting close to where my issues begin (if your still reading, thank you for that
- (void)updateDeparturesFromActionSheet
{
//Dismiss the actionSheet
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
//Send the selected entry from UIPickerView to currentAddress property in FeedStore, fetchSite method will eventually use this
[[FeedStore sharedStore] setCurrentAddress:[pickerViewController addressFromPickerView]];
//Call fetchSite method
[self fetchSite];
}
fetchSite then eventually calls fetchEntries method, which eventually populate my table. I store received obj (from block) in an property called channel
void (^completionBlock)(RSSChannel *obj, NSError *err) = ^(RSSChannel *obj, NSError *err) {
if (!err) {
//If everything went ok, grab the object, and reload the table and end refreshControl
channel = obj;
The channel object looks like this
channel RSSChannel * 0x07464340
NSObject NSObject
currentString NSMutableString * 0x00000000
lvc ListViewController * 0x08c455d0
items NSMutableArray * 0x08c452d0
sites NSMutableArray * 0x08c452f0
parentParserDelegate id 0x00000000
pickerViewArray NSMutableArray * 0x08c45320
As you can see when I populate my tables cells, I use the info from items inside of the channel object.
Now if your still with me (and havnt fallen asleep) so far I will explain my actual problem, now when you have (hopefully) all the relevant code.
So when I press okButton in my UIActionSheet, updateDeparturesFromActionSheet method gets called. Which calls fetchSite which eventually calls fetchEntries and so far so good, these blocks performs and I get back information. But when I grab fetchEntries obj and put it in channel, it doesnt seems to "update" this object with the new information grabbed by the blocks obj object. Among others it does not seems that channel object gets a new place in the memory (it keeps 0x07464340).
My first thought was to make sure channel object gets released by ARC, by removing all owners of that object, but it seems that even if I do so (and then doublecheck that its null with simple NSLog(#"%#") it keeps getting its old values and memory reference back when I trigger the "update".
After many attempts to release the channel object and doing all sorts of stuff (creating new arrays (outside of block) amongst other things). I keep thinking that some special rule within blocks that I dont understand is messing with me. Any ideas?
Please let me know if anything isnt clear because I've expressed myself bad, its hard to explain an issue that you dont understand yourself. Thanks in advanced.

How to adjust the frame of right accessor to top right in MapView annotation?

I want to add the right accessor image(cross image) to the top right corner as shown in the image below, but i am not able to get the code for it:
I am using the following code but its not giving me what i need.I need the cross button at the place shown in the image below.
annView.leftCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd];
UIImage *listImage = [UIImage imageNamed:#"Close_normal.png"];
UIButton *listButton = [UIButton buttonWithType:UIButtonTypeCustom];
// get the image size and apply it to the button frame
// listButton.frame = CGRectMake(0,0,56,68);
CGRect listButtonFrame = listButton.frame;
listButtonFrame.size = listImage.size;
listButton.frame = listButtonFrame;
[listButton setImage:listImage forState:UIControlStateNormal];
annView.rightCalloutAccessoryView = listButton;
And then also what i have to do is when i click on the cross button it should close the info pop up and remove the annotation
- (void) mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
if( // left accessor is clicked then execute this code) // what should i write here
{
SiteAnnotation *site = (SiteAnnotation *)view.annotation;
if(site.category == -1) {
if(addressAnnotation) {
[mapView removeAnnotation:addressAnnotation];
AddViewController *vc = [[[AddViewController alloc] initWithCoordinate:addressAnnotation.coordinate] autorelease];
[self.delegate pushViewController:vc animated:YES];
}
}
else {
[self showSiteDetails:site.identifier];
}
}
else if (// if right accessor cross image is clicked)
{
// Then here the code to dismiss the pop up and annotation pin on map
}
}
You can check this code:
use tags in the above method and control tag to get that tag working below..
annView.leftCalloutAccessoryView.tag=1;
annView.rightCalloutAccessoryView.tag=2;
- (void) mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
SiteAnnotation *site = (SiteAnnotation *)view.annotation;
// Left Accessory Button Tapped
if(site.category == -1) {
if ([control tag] == 1) {
if(addressAnnotation) {
so on...
}
next try
else if ([control tag] == 2) {
// "Right Accessory Button Tapped
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"Touch and hold the pin icon to drag it around." delegate:nil cancelButtonTitle:nil otherButtonTitles:#"Done", nil];
[alert1 show];
[alert1 release];
}
then in the method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
UIAlertView *alert_pin = [[UIAlertView alloc] initWithTitle:#"" message:#"cancel button click it " delegate:nil cancelButtonTitle:nil otherButtonTitles:#"Done", nil];
[alert_pin show];
[alert_pin release];
[mapView removeAnnotation:addressAnnotation];
[addressAnnotation release];
addressAnnotation = nil;
}
use alert and ask user to dismiss it or not rather using direct dismiss button on callout only.

How do I send actions to a UIImage Subview, delegated from a UIAlertView

Essentially I have a UIAlertView that pops up. When a user selects a button it calls itself, and based on the button index it brings up a UIImageView subview. My question is, because the UIImageView takes up a good portion of the screen it lays on top of the UIAlertView, so the cancel button is unseen. I was wondering if I could create actions on the UIImageView so that if it is clicked or touched up inside, the UIAlertView/UIImageView would resign and disappear?
Someone please help, I've been tooling around this for hours.
Here is the code from the button being clicked, and the button index.
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
// exit(0);
}
else
{
UIAlertView *successAlert = [[UIAlertView alloc] initWithTitle:#"molecule" message:molURL delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 280, 260)];
NSString *MyURL = molURL;
NSString *apURL = [NSString stringWithFormat:#"%#",MyURL];
NSURL * imageURL = [NSURL URLWithString:apURL];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * image1 = [UIImage imageWithData:imageData];
//UIImage *bkgImg = [[UIImage alloc] initWithContentsOfFile:path];
[imageView setImage:image1];
[successAlert addSubview:imageView];
[successAlert show];
}
}
MyImageView.h
#import <UIKit/UIKit.h>
#interface MyImageView : UIImageView {
}
#end
MyImageView.m
#import "MyImageView.h"
#implementation MyImageView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.userInteractionEnabled=YES;
}
return self;
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[UIView animateWithDuration:2.0f animations:^(void) {
self.alpha=0.0f;
super.hidden =YES;
UIAlertView *alert=(UIAlertView*)self.superview;
alert.alpha=0.0f;
[alert dismissWithClickedButtonIndex:0 animated:YES];
//or
//[alert removeFromSuperview];
}];
}
- (void)dealloc {
[super dealloc];
}
#end
MyViewController.h
#class MyImageView;
MyViewController.m
#import "MyImageView.h"
then while create imageView
MyImageView *specialImageView =[[MyImageView alloc]initWithFrame:CGRectMake(0, 0, 280, 260)];

adding action to alertView Button

I everybody,
I have 3 Buttons each one calls an AlertView with "Cancel" and "OK" and each "OK" Button goes to an different view.
for now I solved this with this
- (UIButton *)1_BTN
{
if (1_BTN == nil)
{
UIImage *buttonBackground = [UIImage imageNamed:#"1_btn.png"];
UIImage *buttonBackgroundPressed = [UIImage imageNamed:#"1_btn.png"];
CGRect frame = CGRectMake(655, 985, 107, 30);
1_BTN = [_IPadAppDelegate buttonWithTitle:#""
target:self
selector:#selector(1_BTN:)
frame:frame
image:buttonBackground
imagePressed:buttonBackgroundPressed];
[1_BTN setTag:1];
}
return 1_BTN;
}
......
- (void)1_BTN:(NSInteger *)sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"some fancy text" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"ok", nil];
[alert setTag:[sender valueForKey:#"tag"]];
[alert show];
[alert release];
}
.......
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
if ([[alertView tag] isEqualToNumber:[NSNumber numberWithInt:1]]) {
something should happen.....
}
for all three Buttons and it works fine but for
[alert setTag:[sender valueForKey:#"tag"]];
and
if ([[alertView tag] isEqualToNumber:[NSNumber numberWithInt:1]]) {
i get this warning "Invalid receiver Type "NSInteger""
why is that so and how can I solve this better?
For one thing, you're doing this entirely wrong. Implement the UIAlertViewDelegate, specifically alertView:clickedButtonAtIndex: and check which button index (from 0 .. n where n is the last button). Act accordingly based on your known fixed indices.
Secondly, NSInteger is a scalar non-object type, and cannot receive messages. You would want an equality comparison instead, i.e., alertview.tag == 1. But as I said previously, don't do it that way.
The UIView property "tag" isn't an object, it is just a simple NSInteger. It's almost the same as "int" you probably know from C/C++. I corrected a few line in your code. Now it should work.
Another thing: The allocation of the UIButton seems a bit strange to me. Maybe you should check your memory management.
- (UIButton *)1_BTN
{
if (1_BTN == nil) {
UIImage *buttonBackground = [UIImage imageNamed:#"1_btn.png"];
UIImage *buttonBackgroundPressed = [UIImage imageNamed:#"1_btn.png"];
CGRect frame = CGRectMake(655, 985, 107, 30);
1_BTN = [_IPadAppDelegate buttonWithTitle:#"" target:self selector:#selector(1_BTNAction:) frame:frame image:buttonBackground imagePressed:buttonBackgroundPressed];
[1_BTN setTag:1];
}
return 1_BTN;
}
- (void)1_BTNAction:(UIButton *)sender {
NSInteger tagNumber = [sender tag];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"sone fancy text" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"ok", nil];
[alert setTag:tagNumber];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
if ([alertView tag] == 1) {
//something should happen
}
}
}

Resources