Getting the image from a UIButton - objective-c

I'm trying to get the image assigned to a button on click, so I can assign it to something else when the button is clicked.
I think I'm nearly there, I've managed to get the following info from the button
Sender info is: <UIImageView: 0x757d9b0; frame = (0 0; 100 100); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x757da10>> - image-name.png
As you can see, the image name is appended at the end of the log but I'm not sure how to get just that.
The code I've used to get this is:
sender.imageView
Thanks in advance for any help
EDIT:
Thanks to #zoul for leading me on the right path.
I ended up doing the following:
UIImage *image = [sender imageForState:UIControlStateNormal];
[self.newButton setImage:image forState:UIControlStateNormal];

There’s an imageForState: method on UIButton.

Related

UICollectionViewCell hidden though I never set it hidden

I'm quite amazed by the result I get from those lines:
[cell setHidden:NO];
NSLog(#"CELL = %#", cell);
NSLog(#"HIDDEN = %hhd", cell.hidden);
Output:
2015-06-13 19:35:53.923 CELL = <DetailedSqeedCollectionViewCell: 0x145660b0; baseClass = UICollectionViewCell; frame = (-20 -49; 0 0); clipsToBounds = YES; hidden = YES; opaque = NO; layer = <CALayer: 0x1582cd90>>
2015-06-13 19:35:53.923 HIDDEN = 1
How is it possible, does anyone have a clue?
Thanks in advance.
I had this problem. iOS is smart enough to hide cells if the underlying subviews, in my case the imageView's frame was outside the bounds and not showing. Make sure if any subviews you have are set properly.
You will also find that if you set the background cell color to something that does not match the UICollectionView, it will not be shown hidden anymore.

Weird behaviour of UIButton with tintColor on enabled/disabled states

UPDATE:
Even UIBarButtonItems do not respond to state change, visually.
The scenario:
I have a UIButton of type UIButtonTypeSystem initialized as below:
sendButton = [UIButton buttonWithType:UIButtonTypeSystem];
sendButton.backgroundColor = [UIColor clearColor];
[sendButton setTintColor:UIColorFromRGB(SEND_BUTTON_COLOR)];
sendButton.opaque = YES;
sendButton.clearsContextBeforeDrawing = NO;
sendButton.frame = CGRectMake(275, 6, 50, 35);
UIImage* sendImage = [UIImage imageNamed:#"toilet_paper"];
[sendButton setImage:[UIImage imageWithCGImage:sendImage.CGImage scale:sendImage.scale orientation:UIImageOrientationLeft]
forState:UIControlStateNormal];
sendButton.enabled = NO;
[sendButton addTarget:self action:#selector(post) forControlEvents:UIControlEventTouchUpInside];
The Purpose:
It is associated with a UITextView such that it is set to enabled if there is some text in the textView AND my host is available (checked through Reachability) and it's enabled property is changed in textViewDidChange: delegate method with the following:
sendButton.enabled = [APP_DELEGATE hostAvailable] && [myTextView.text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#" \n"]].length > 0;
According to this enabled state, the button must toggle between SEND_BUTTON_COLOR (enabled = YES) and grayColor (enabled = NO).
The Problem:
Up until now, the code used to work fine. It was gray when there was no text in the textView and it became SEND_BUTTON_COLOR as soon as there was some text in the textView. However, out of the blue, it has stopped this behaviour. What happens is, it stays gray all the time irrespective of the content of the textView. Once it is pressed, it becomes SEND_BUTTON_COLOR and stays that way, again irrespective of the textView text.
How do I regain the behaviour of the button I used to have on my UIButton?
You have to set your button's tint color again in the textViewDidChange delegate method.
In your delegate where you are setting the enabled state:
sendButton.enabled = [APP_DELEGATE hostAvailable] && [myTextView.text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#" \n"]].length > 0;
if(sendButton.enabled){
[sendButton setTintColor:UIColorFromRGB(SEND_BUTTON_COLOR)];
}
else{
//Set Another Color For Disabled State
}
As it appears, the problem was on my part. I had subclassed UIButton in the .m file of a different VC (not imported by the VC in question, or any other VCs it had imported):
#implementation UIButton (Border)
- (void) setEnabled:(BOOL)enabled {
if (enabled) {
self.layer.borderColor = UIColorFromRGB(0x888888).CGColor;
} else {
self.layer.borderColor = UIColorFromRGB(0xdddddd).CGColor;
}
[super setEnabled:enabled];
[self setNeedsDisplay];
}
#end
Somehow, this interfered with my button. After weeks of further subclassing, changing images, changing titles, etc, I was able to diagnose the issue (accidentally) by jumping to definition (CMD + Click) of the enabled method, and it took me straight to the source of the issue (the subclass code). Commented it out, and voila. Things were back to normal.
I hope this helps someone in the future who faces the same issue (or makes the same mistake I did).

How to show several subviews?

I'm having what I think is a bit of a newbie problem...
I've made a dynamic scroll view where images and labels are programmatically added as subviews. Problem is that only the last one I'm adding as a subview is showing.
Also when I read about "addSubview:" it says "Adds a view to the end of the receiver’s list of subviews." Does this mean only the last added subview is supposed show? In that case how do I make both visible?
Thanks in advance,
Tom
CODE:
for(int i = 0; i < [famorableArray count]; i++){
UIButton *famorableButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[famorableButton setFrame:CGRectMake(0.0f, 5.0f, 57.0f, 57.0f)];
[famorableButton setImage:personLogo forState:UIControlStateNormal];
NSString *famString = [NSString stringWithFormat:#"%#", [[[famorableArray objectAtIndex:i] substringFromIndex:8] capitalizedString]];
NSLog(#"%#", famString);
UILabel *famLabel = [[UILabel alloc] initWithFrame:CGRectZero];
famLabel.text = famString;
NSLog(#"Test2 %#", famLabel.text);
// Move the buttons position in the x-demension (horizontal).
CGRect btnRect = famorableButton.frame;
btnRect.origin.x = totalButtonWidth;
[famorableButton setFrame:btnRect];
CGRect labelRect = famLabel.frame;
labelRect.origin.x = totalButtonWidth + 28.5f;
[famLabel setFrame:btnRect];
// Add the button to the scrollview
[famScroll addSubview:famLabel];
[famScroll addSubview:famorableButton];
// Add the width of the button to the total width.
totalButtonWidth += famorableButton.frame.size.width + 30;
}
[famScroll setContentSize:CGSizeMake(totalButtonWidth, 79.0f)];
For each added subview you have to set the frame property. The frame is the view's position in the superview. "Adding to the list of subviews" does not imply any automatic layout. So I assume that all your subviews are visible but overlap.
My bad... It was a fail editing after copy paste. Accidentally used btnRect as a frame for the label too. Thanks for your effort anyways #Martin :)

how load many photos from url in background (asynchronous)

i have this method i use to load many images to scroll view, but when the images load from the url my scroll view is stuck and i can't understand how to load them in the background so the user will not feel it.
this method will call few times (8) in "for" cycle.
- (void)loadPhotosToLeftscroll{
//getting image information from JSON
NSMutableDictionary *photoDict;
photoDict = [leftPhotoArray lastObject];
//getting the photo
NSString *photoPath = [photoDict objectForKey:#"photos_path"];
NSLog(#"photo Path:%#",photoPath);
NSData * imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:photoPath]];
UIImage *image = [UIImage imageWithData:imageData];
// use the image how you like, say, as your button background
//calculating the hight of next photo
UIImageView *leftImage = [leftBlockScroll.subviews lastObject];
//allocating photoView
UIImageView *photoView = [[UIImageView alloc]initWithFrame:CGRectMake(5 , leftImage.frame.origin.y + leftImage.frame.size.height+5, image.size.width/2, image.size.height/2 )];
photoView.userInteractionEnabled=YES;
[photoView.layer setMasksToBounds:YES];
[photoView.layer setCornerRadius:3];
//getting items list
NSDictionary *sh_items = [photoDict objectForKey:#"items"];
//adding image button
UIButton *imageOverButton = [UIButton buttonWithType:UIButtonTypeCustom];
imageOverButton.frame = CGRectMake(0, 0, photoView.frame.size.width, photoView.frame.size.height);
[imageOverButton addTarget:self action:#selector(LeftimagePressed:) forControlEvents:UIControlEventTouchUpInside];
[imageOverButton setTag:[leftPhotoArray count]-1];
[photoView addSubview:imageOverButton];
//adding sh button to imageView
[self addThe_sh_signs:sh_items To_ImageView:photoView];
//subViewing the image to the scrollView
[self insert_Image:image toImageView:photoView in_Scroll:leftBlockScroll];
//calclulating the position of next imageView in scroll.
nextLeftPhotoHight = photoView.frame.size.height + photoView.frame.origin.y + 5;
//calculating the hight of the highest scroll view in both.
leftBlockScroll.contentSize = CGSizeMake(160, [self theSizeOfScrollViewHight]);
rightBlocScroll.contentSize = CGSizeMake(160, [self theSizeOfScrollViewHight]);
isLoadindContant = NO;
[self.view reloadInputViews];
[leftBlockScroll reloadInputViews];
}
please do not send me to some link that trying to explain how to use the asynchronous.
Try to explain according the method you see here.
Im here for any question, that you need to ask to help me.
You will have to do it asynchronously in a proper way. I do not think there is any way around that. I subclassed an UIImageView object and placed many instances of it within the cells of a talbe (in your case within the scroll view). The subclass objects are initialized with an url and load their image asynchronously (with some caching so that the image is not loaded every time).
This tutorial helped me much in the beginning:
http://www.markj.net/iphone-asynchronous-table-image/
You will just have to adopt that to your scroll view. The underlaying principle remains the same.

UIImageView blurs image

I have a really weird problem with UIImageView. I have an image (an RGB png) 45x45 pixels which I add to the view. I can see that image is blurred after added to the view. Here is the same image in the simulator (left) and in Xcode (right):
(source: partywithvika.com)
(source: partywithvika.com)
I have custom UIImageView class with this initWithImage code:
- (id) initWithImage:(UIImage*) image {
self = [super initWithImage:image];
self.frame = CGRectMake(0, 0, 45, 45);
self.contentMode = UIViewContentModeScaleAspectFit;
self.quantity = 1;
if (self) {
self.label = [[UITextField alloc]initWithFrame:CGRectMake(0,40,45,25)];
self.label.font = [UIFont systemFontOfSize:16];
self.label.borderStyle = UITextBorderStyleNone;
self.label.enabled = TRUE;
self.label.userInteractionEnabled = TRUE;
self.label.delegate = self;
self.label.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
self.label.textAlignment = UITextAlignmentCenter;
}
self.userInteractionEnabled = TRUE;
// Prepare 3 buttons: count up, count down, and delete
self.deleteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.deleteButton.hidden = NO;
self.deleteButton.userInteractionEnabled = YES;
self.deleteButton.titleLabel.font = [UIFont systemFontOfSize:20];
self.deleteButton.titleLabel.textColor = [UIColor redColor];
[self.deleteButton setTitle:#"X" forState:UIControlStateNormal];
[self.deleteButton addTarget:self action:#selector(deleteIcon:) forControlEvents:UIControlEventTouchUpInside];
self.upCountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.upCountButton.hidden = NO;
self.upCountButton.userInteractionEnabled = YES;
[self.upCountButton setTitle:#"+" forState:UIControlStateNormal];
[self.upCountButton addTarget:self action:#selector(addQuantity:) forControlEvents:UIControlEventTouchUpInside];
self.downCountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.downCountButton.hidden = YES;
self.downCountButton.userInteractionEnabled = YES;
[self.downCountButton setTitle:#"-" forState:UIControlStateNormal];
[self.downCountButton addTarget:self action:#selector(removeQuantity:) forControlEvents:UIControlEventTouchUpInside];
return self;
}
I create it like this:
UIImage *desertIcon = [UIImage imageNamed:#"desert.png"];
IconObj *desertIconView = [[IconObj alloc] initWithImage:desertIcon];
desertIconView.center = CGPointMake(265,VERTICAL_POINT_ICON);
desertIconView.type = [IconObj TYPE_DESERT];
[self.view addSubview:desertIconView];
[desertIconView release];
Why would the displayed image be so than the one stored in a file?
In general, everything you do on iPhone with UIKit should be pixel-aligned. Problems with pixel alignment usually manifest as blurriness (this is especially true with text and images). This is why when I find blurry view, I first check if I'm setting the center property. When you set center, the frame's x, y, height and width are adjusted around that center point... frequently resulting in fractional values.
You could try using CGRectIntegral on the frame as shown:
desertIconView.center = CGPointMake(265,VERTICAL_POINT_ICON);
desertIconView.frame = CGRectIntegral(desertIconView.frame);
This may work, but if it doesn't, try setting the frame manually, without using center property to ensure that no values are fractional.
Edit: Whoops! Didn't notice that the OP had answered his own question... I'll leave this up for informational reasons anyway.
I had this problem and it was driving me nuts. After some investigation it turned out that my image was smaller than the frame, and hence the scaling up blurred it. Once I had put in higher resolution images the problem is gone.
Make sure your image size is greater than your UIImageView frame size.
Your IconObj is 45 pixels wide. You move your IconObj center to 265 which makes its frame to (242.5, VERTICAL_POINT_ICON - 25*0.5, 45, 25). Image will always be blur if some of frame parameter is not integer.
Solution, calculate the frame parameter yourself (don't use center). And always make it integer (cast to NSInteger, use ceil, floor, or round).
desertIconView.frame = CGRectMake((NSInteger)(265 - 45*0.5),
(NSInteger)(VERTICAL_POINT_ICON - 25*0.5),
45, 25);
What I ended up doing is loading bigger picture into 45x45 UIImageView, of course with
contentMode = UIViewContentModeScaleAspectFit;
I just had the same problem. First I thought wtf do I need glasses?
Then I realized it´s just not possible to center an image (or label) when you give it an odd number. You need to resize your image to e.g. 46*46 if you want to center it and stay sharp.
Or you can leave it at 45*45 but then you need to decide whether you want your image to be mal-centered 1 pixel to the right, or 1 pixel to the left. (or leave it blurry).
Try to align your IconObj view at screen pixels. If it's really 45x45 then you should set the center to something like CGPointMake(x + 0.5f, y + 0.5f).
You should also double check image size in pixels (e.g in Preview.app Command-I).
complete source for the offset problem:
contentImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
UIImage *cImage = [UIImage imageNamed:image];
self.contentImage.image = cImage;
[self.contentImage setFrame:CGRectMake(0, 0, cImage.size.width, cImage.size.height)];
CGFloat offset = 0.0f;
if ( ( (int)cImage.size.width % 2 ) && ( (int)cImage.size.height % 2 ) ) {
offset = 0.5f;
}
[self.contentImage setCenter:CGPointMake(256.0f + offset, 256.0f + offset)];