Remove and add multiple image in same UIImageView - ios

I am designing a make own pizza app. The user would add multiple toppings for example shrimp, bacon, and etc. on top of each other. So the adding image is working fine. Here is my code:
bool meatAdded;
- (void)addMeatTopping:(NSString*)meat withImage:(UIImageView*)meatImage {
if ((meatAdded =! meatAdded)) {
//crust o taqir bede be cheese BADAN
meatImage = [[UIImageView alloc]initWithFrame:_crustImage.bounds];
[meatImage setImage:[UIImage imageNamed:meat]];
[_crustImage addSubview:meatImage];
for (UIButton*button in _meatButtonsArray) {
checkMark.center = button.center;
checkMark.alpha = 1;
}
[UIView animateWithDuration:.60 delay:0 usingSpringWithDamping:.40 initialSpringVelocity:.20 options:UIViewAnimationOptionAllowUserInteraction animations:^ {
meatImage.transform = CGAffineTransformMakeScale(.5, .5);
meatImage.transform = CGAffineTransformMakeScale(1, 1); } completion:nil];
}else {
/**** THIS PART OF CODE DOESN'T WORK ! IT PRINTS LOG BUT DOESN'T CHANGE THE MEAT IMAGE AT ALL ****/
NSLog(#"Remove");
meatImage.alpha = 0;
[meatImage setImage:nil];
[meatImage removeFromSuperview];
}
}
example of calling above method:
- (IBAction)meat0:(id)sender {
[self addMeatTopping:#"topping_Bacon" withImage:beykenMeat];
}
- (IBAction)meat1:(id)sender {
[self addMeatTopping:#"Steak" withImage:steykMeat];
}
How can I create a toggle method when user select an item? The item will add to view and when taps again it should be removed from view.

SubclassImageView *imageviewG = [[SubclassImageView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
self.crustImage = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 250, 250)];
self.crustImage.backgroundColor = [UIColor redColor];
[imageviewG setImage:#"topping_Bacon"];
[self.crustImage addSubview:imageviewG];
[self.view addSubview:self.crustImage];
for(id viewInner in self.crustImage.subviews){
if([viewInner isKindOfClass:[SubclassImageView class]]){
SubclassImageView *imageSeleted = (SubclassImageView *)viewInner;
if([imageSeleted.getImageName isEqualToString:#"topping_Bacon"]){
//your logic to add or remove the imageview from super view
}else if([imageSeleted.getImageName isEqualToString:#"Steak"]){
//your logic to add or remove the imageview from super view
}
}
}

Related

reading taps on titleview field iOS

I'm having a problem with reading taps on navigation bar (I need to open dropdown menu by tapping on title field, just like in telegram and etc. but not in swift)
I know that basically its unreadable, and already've tried with taprecognizer, but it didn't work for me any good.
Now my menu opens with rightbarbutton - that's ugly.
How can I deal with it?
Now string that drops menu (placed in viewDidLoad) looks like:
navbar = [[UIBarButtonItem alloc]initWithTitle:#"navbar" style:UIBarButtonItemStylePlain target:self action:#selector(navigationTitleTapGestureAction:)];
and a part that declares button:
NSArray *buttons = #[navbar <<...a few more buttons...>>];
self.navigationItem.rightBarButtonItems = buttons;
EDIT: additional code from the comments:
- (IBAction)navigationTitleTapGestureAction:(id)sender {
automaticDisappearanceCanceled_ = YES;
if (menuToolbarVisible_) {
[self hideMenuAnimated:YES];
}
else {
[self showMenuAnimated:YES];
}
}
- (void)showMenuAnimated:(BOOL)animated {
[self.view layoutIfNeeded];
self.toolbarTopLayoutConstraint.constant = 0.f;
self.menuToolbar.hidden = NO;
[UIView animateWithDuration:animated ? ToolbarMenuAnimationDuration : 0.f animations:^{
[self.view layoutIfNeeded];
} completion: ^(BOOL finished) {
}];
menuToolbarVisible_ = YES;
}
- (void)hideMenuAnimated:(BOOL)animated {
[self.view layoutIfNeeded];
self.toolbarTopLayoutConstraint.constant = -ToolbarMenuHeight;
[UIView animateWithDuration:animated ? ToolbarMenuAnimationDuration : 0.f animations: ^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
self.menuToolbar.hidden = YES;
}];
menuToolbarVisible_ = NO;
}
As far is I know you just want to get taps on the text on the center of navigation bar you can do this by adding a UIButton in the titleView like this :-
UIButton *centerButton=[[UIButton alloc]initWithFrame:CGRectMake(0, 0, 44.0, 44.0)];
[centerButton setTitle:#"Center" forState:UIControlStateNormal];
[centerButton addTarget:self action:#selector(action) forControlEvents:UIControlEventTouchDown];
self.navigationItem.titleView=centerButton;

VBPieChart - removeFromSuperView not working (hide chart)

I'm using VBPieChart, in Objective C language. I'm showing the chart on valueChange of a segmented control, like :
- (IBAction)segmentControlAction:(UISegmentedControl *)sender
{
switch ([sender selectedSegmentIndex])
{
case 0:
[self showPieChart:NO];
_tableViewForCount.hidden = NO;
[_tableViewForCount reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationRight];
break;
case 1:
_tableViewForCount.hidden = YES;
[self showPieChart:YES];
break;
default:
NSLog(#"None");
break;
}
}
and the showPieChart method goes like :
- (void) showPieChart:(Boolean)visible
{
VBPieChart *chart = [[VBPieChart alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
chart.center = self.view.center;
// Setup some options:
[chart setHoleRadiusPrecent:0.3]; /* hole inside of chart */
// Prepare your data
NSMutableArray *chartValues = [[NSMutableArray alloc]initWithObjects: #{#"name":#"Apples", #"value":#50, #"color":[UIColor redColor]},
#{#"name":#"Pears", #"value":#20, #"color":[UIColor blueColor]},
#{#"name":#"Oranges", #"value":#40, #"color":[UIColor orangeColor]},
#{#"name":#"Bananas", #"value":#70, #"color":[UIColor purpleColor]}, nil
];
if (visible)
{
chart.center = self.view.center;
// Present pie chart with animation
[chart setChartValues:chartValues animation:YES duration:0.4 options:VBPieChartAnimationFan];
[self.view addSubview:chart];
}
else
{
// remove chart
[chart removeFromSuperView];
}
}
Since VBPieChart is just a custom subclass of UIView, this should work. But i'm not getting any success.
I've also tried [chart setHidden:YES]; as well as [chart setAlpha:0.0]; , but still no luck.
Any help would is appreciated. I just want to hide/remove the chart when user switched back to segment index 0.
Thanks.
VBPieChart *chart create this object on the .h file then
- (void) showPieChart:(Boolean)visible
{
if(chart == nil)
{
chart = [[VBPieChart alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
[self.view addSubview:chart];
}
chart.center = self.view.center;
// Setup some options:
[chart setHoleRadiusPrecent:0.3]; /* hole inside of chart */
// Prepare your data
NSMutableArray *chartValues = [[NSMutableArray alloc]initWithObjects: #{#"name":#"Apples", #"value":#50, #"color":[UIColor redColor]},
#{#"name":#"Pears", #"value":#20, #"color":[UIColor blueColor]},
#{#"name":#"Oranges", #"value":#40, #"color":[UIColor orangeColor]},
#{#"name":#"Bananas", #"value":#70, #"color":[UIColor purpleColor]}, nil
];
if (visible)
{
chart.center = self.view.center;
// Present pie chart with animation
[chart setChartValues:chartValues animation:YES duration:0.4 options:VBPieChartAnimationFan];
chart.alpa = 1.0
}
else
{
// remove chart
chart.alpa = 0.0
}
}
You need to create variable as below.
static VBPieChart *chart = nil
if(!chart)
chart = [[VBPieChart alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
}
if (visible)
{
chart.hidden = NO;
}
else
{
// hide chart
chart.hidden = YES;
}

Animation does not origin from where I want it to? Why?

I'm doing a countdown clock to my game. I want the numbers to be animated so they come from the middle of the screen and then fade away in the middle. But when I run the code they will come from the right bottom of the screen instead of where I specified it (160,284). What could the problem be?
} else if (startgameEveryInt == 3) {
UIImageView *Object = [[UIImageView alloc] initWithFrame:CGRectMake(160,284,280 ,280)];
[Object setImage:[UIImage imageNamed:#"1.png"]];
[self.view addSubview:Object];
[UIView animateWithDuration:1
animations:^{
Object.alpha = 0;
Object.frame = CGRectMake(160, 284, 50, 50);
}
completion:^(BOOL finished){
startgameEveryInt = 0;
[startgametimer invalidate];
startgametimer = nil;
[self startit];
for (UIView *view in self.view.subviews) {
if (view.tag > 10) {
[view removeFromSuperview];
}
}
}];
}
If you change your CGRect settings to for before the animation-
CGRectMake((self.view.frame.size.width-160)/2, (self.view.frame.size.height-284)/2, 160, 284)
Then changing the size of the object as you did before to
CGRectMake((self.view.frame.size.width-50)/2, (self.view.frame.size.height-50)/2, 50, 50)
This should work for you in the middle of the screen. The X, Y positions of the CGRect will put the top LHS points of your object to that position. This is why your object looked like it was off to the bottom right.
I hope this helps
Cheers, Jim

Subclassed UIView not displaying proper after animating frame

I have subclassed UIView to contain basically a UIPickerView and a UIToolbar.
When the user selects a particular row in the picker I will then add a UIImageView over the picker. However this image is not visible when I have animated my UIView to slide up the screen. If I don't animate the UIView then it will display properly.
I'm displaying the UIImageView like this (in the UIView):
- (void)showMailSetupPopover {
if (self.popoverMailSetupImageView == nil) {
UIImageView *popoverMailSetupImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"popover-mail-setup-addreminder"]];
popoverMailSetupImageView.alpha = 0.0;
popoverMailSetupImageView.frame = CGRectMake(8, self.frame.origin.y + 65, popoverMailSetupImageView.bounds.size.width, popoverMailSetupImageView.bounds.size.height);
self.popoverMailSetupImageView = popoverMailSetupImageView;
}
[self addSubview:self.popoverMailSetupImageView];
[UIView animateWithDuration:0.5 animations:^{
self.popoverMailSetupImageView.alpha = 1.0;
} completion:^(BOOL finished) {}];
}
This is how I add theUIView to self.view:
RMMessageTypePickerView *messageTypePickerView = [[RMMessageTypePickerView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, 320, 260) reminderMessageType:RMReminderMessageTypeText delegate:self];
self.messageTypePickerView = messageTypePickerView;
[self.view addSubview:self.messageTypePickerView];
[UIView animateWithDuration:0.2 animations:^{
self.messageTypePickerView.frame = messageTypePickerViewTargetFrame;
self.addReminderTableView.frame = addReminderTableViewTargetFrame;
} completion:^(BOOL finished) {
if (firstShow) {
[self processSelectedMessageTypeRow:RMReminderMessageTypeText];
}
}];
Found out the issue,
Replaced
popoverMailSetupImageView.frame = CGRectMake(8, self.frame.origin.y + 65, popoverMailSetupImageView.bounds.size.width, popoverMailSetupImageView.bounds.size.height);
with
popoverMailSetupImageView.frame = CGRectMake(8, 65, popoverMailSetupImageView.bounds.size.width, popoverMailSetupImageView.bounds.size.height);
self.frame.origin.y is not needed.

CustomAnnotationView with a button

I've been strunggling with an issue on my project :
I've a mapView and I have to show the annotation presented below (The small (+) is my button)
I've subclassed MKAnnotationView and I have CustomAnnotationView.h like this :
#interface CustomAnnotationView : MKAnnotationView
#property (strong, nonatomic) UIImageView *calloutView;
#property (strong, nonatomic) UIButton *pinButton;
#property (strong, nonatomic) UIView *annView;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
- (void)animateCalloutAppearance;
My CustomAnnotationView.m
- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
[super setSelected:selected animated:animated];
if(selected)
{
//building my custom animation
annView = [[ UIView alloc ] initWithFrame:(CGRectMake(0, 0, 30, 30)) ];
annView.frame =CGRectMake(0, 0, 200, 50);
calloutView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"customcallout.png"]];
[calloutView setFrame:CGRectMake(-25, 50, 0, 0)];
[calloutView sizeToFit];
[self animateCalloutAppearance];
//I tried to add a button here but I could't do it like it should be
[annView addSubview:calloutView];
[self addSubview:annView];
}
else
{
//Remove your custom view...
[annView removeFromSuperview];
}
}
- (void)didAddSubview:(UIView *)subview{
if ([[[subview class] description] isEqualToString:#"UICalloutView"]) {
for (UIView *subsubView in subview.subviews) {
if ([subsubView class] == [UIImageView class]) {
UIImageView *imageView = ((UIImageView *)subsubView);
[imageView removeFromSuperview];
}else if ([subsubView class] == [UILabel class]) {
UILabel *labelView = ((UILabel *)subsubView);
[labelView removeFromSuperview];
}
}
}
}
- (void)animateCalloutAppearance {
CGFloat scale = 0.001f;
calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, -50);
[UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationCurveEaseOut animations:^{
CGFloat scale = 1.1f;
calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, 2);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
CGFloat scale = 0.95;
calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, -2);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.075 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
CGFloat scale = 1.0;
calloutView.transform = CGAffineTransformMake(scale, 0.0f, 0.0f, scale, 0, 0);
} completion:nil];
}];
}];
}
#end
With this I'm able to show my custom annotation on the map but I can't figure out how to place a button on it and this button should of course be able to respond to clicks like the callback calloutAccessoryControlTapped:
Please anyone with a working example code or idea.
Thank you.
I solved this using - (UIView*)hitTest in my CustmAnnotationView.m class. I have a separate nib for the callout view and use hittest to determine whether the UILabel named directionsButton (linked from the callout nib) was clicked:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
if (selected) {
calloutVisible = YES;
hitTestBuffer = NO;
self.calloutView = [[[NSBundle mainBundle] loadNibNamed:#"CalloutView" owner:self options:nil] objectAtIndex:0];
[directionsButton setFont:[UIFont fontWithName:#"DIN-Medium" size:12.0f]];
[calloutView setFrame:CGRectMake(calloutView.frame.origin.x, calloutView.frame.origin.y, 280, calloutView.frame.size.height)];
[calloutView setAlpha:0.0f];
[self addSubview:calloutView];
[self sendSubviewToBack:calloutView];
[UIView animateWithDuration:0.3f delay:0.0f options:0 animations:^{
[calloutView setAlpha:1.0f];
} completion:^(BOOL finished) {
}];
[super setSelected:selected animated:animated];
} else {
calloutVisible = NO;
CGRect newFrame = self.frame;
newFrame.size.width = 52;
self.frame = newFrame;
[UIView animateWithDuration:0.3f delay:0.0f options:0 animations:^{
[calloutView setAlpha:0.0f];
} completion:^(BOOL finished) {
[calloutView removeFromSuperview];
}];
}
}
- (void)directionsPressed
{
if ([parent respondsToSelector:#selector(directionsPressed:)])
[parent performSelector:#selector(directionsPressed:) withObject:self.stockist];
}
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if (calloutVisible) {
CGPoint hitPoint = [calloutView convertPoint:point toView:directionsButton];
if ([calloutView pointInside:hitPoint withEvent:event]) {
if (!hitTestBuffer) {
[self directionsPressed];
hitTestBuffer = YES;
}
return [directionsButton hitTest:point withEvent:event];
} else {
hitTestBuffer = NO;
}
}
return [super hitTest:point withEvent:event];
}
In my code parent is my current VC. This is probably not the neatest way but it worked at the time.
The callout looks like this:
A couple of booleans calloutVisible and hitTestBuffer make sure the button is only clickable once and only when visible.
To try and resolve your issue, I played a bit with Apple's WeatherMap example, and came up with a working solution to your problem.
I added your code to the WeatherAnnotationView.m file (minus the animation code), and on top of that added the code to display the button, and respond to touch events:
-(void)annotationButtonClicked{
NSLog(#"** button clicked");
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
if(selected)
{
//building my custom animation
annView = [[ UIView alloc ] initWithFrame:(CGRectMake(0, 0, 30, 30)) ];
annView.frame =CGRectMake(0, 0, 200, 50);
calloutView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"cloudy.png"]];
[calloutView setFrame:CGRectMake(-25, 50, 0, 0)];
[calloutView sizeToFit];
[annView addSubview:calloutView];
/* BUTTON CODE */
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0,0,20,20)];
button.backgroundColor = [UIColor orangeColor];
[button addTarget:self action:#selector(annotationButtonClicked) forControlEvents:UIControlEventTouchUpInside];
[annView addSubview:button];
/* END Of BUTTON CODE */
[self addSubview:annView];
}
else
{
//Remove your custom view...
[annView removeFromSuperview];
}
}
You haven't posted HOW you tried to add a button to the annView, so it is hard for me to understand what was not working with your approach. A common approach for these kind of problems is to remove one piece of code at a time and try to run your app. For starters, try to remove the animation code. Then, try to remove calloutView, and remain only with annView and the button, until you have code that works with a button. After that, add back the pieces you removed earlier (animation, calloutView) one at a time and see which one is causing your button to stop function.
I hope this helps somehow.

Resources