I have to implement a button with rectangular border and it should be like this
and I am using the following code to do that:
-(void)createDynamicView:(CGRect)frame{
UIButton *drugimgBtn = [UIButton buttonWithType:UIButtonTypeCustom];
drugimgBtn.frame = frame;//CGRectMake(0, 0, 155, 130);
NSString *myurl = responseDrugInfo.ThumbImg; //by rajesh
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myurl]];
UIImage *tbImage = [[UIImage alloc] initWithData:imageData];
[drugimgBtn setBackgroundImage:tbImage forState:UIControlStateNormal];
[drugimgBtn addTarget:self action:#selector(imageButtonAction:) forControlEvents:UIControlEventTouchUpInside];
UIView * prescView = [[UIView alloc]init];
prescView.frame = frame;
prescView.layer.borderColor = [UIColor lightGrayColor].CGColor;
prescView.layer.borderWidth = 1.0f;
[prescView addSubview:drugimgBtn];
[scrollview addSubview:drugimgBtn];
//[prescView release];
[myurl release];
[tbImage release];
}
The output is as follow:
How do I implement a rectangular border so it can appeared like the same in the first image?
Related
I have a large amount of image buttons being added to the screen in an iPhone app. Everything is working fine with my code.
The problem is the subviews are not displaying until every one of the subviews are ready to display. So for example I have 48 subviews, I don't want to wait until every subview is ready, I want to visibly be able to see each one appearing on the screen as they are loading.
I hope this makes sense. The issue is getting larger as i add more images to the collection.
This is my code for you to see:
for (int i = 0; i < imgNumbers.count; i++) {
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect buttonValue = [[btn9Locations objectAtIndex:location] CGRectValue];
myButton.frame = buttonValue;
NSString *imagePart1 = [[NSString alloc] initWithFormat:#"%#", imgNumbers[i]];
[myButton addTarget:self action:#selector(buttonClick:) forControlEvents:UIControlEventTouchDownRepeat];
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [tmpDirURL URLByAppendingPathComponent:imagePart1];
NSString *imageLocation = [[NSString alloc]initWithFormat:#"%#", [fileURL path]];
UIImage * image = [UIImage imageWithContentsOfFile:imageLocation];
[myButton setBackgroundColor:[UIColor colorWithRed:0.94 green:0.39 blue:0.13 alpha:0.0]];
[myButton setBackgroundImage:image forState:UIControlStateNormal];
[myButton setTitle:[imageNames[i] uppercaseString] forState:UIControlStateNormal];
[myButton.titleLabel setFont:[UIFont fontWithName:#"Helvetica-Light" size:20]];
[myButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
[myButton setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
[myButton setTitleColor:[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5] forState:UIControlStateNormal];
myButton.imageView.layer.cornerRadius = 7.0f;
myButton.layer.shadowRadius = 3.0f;
myButton.layer.shadowColor = [UIColor blackColor].CGColor;
myButton.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
myButton.layer.shadowOpacity = 0.5f;
myButton.layer.masksToBounds = NO;
[buttons addObject:myButton];
[scrollview addSubview:myButton]; }
Hope this makes sense, I have seen apps that when you scroll down each item fades onto the screen but I don't seem to be able to sort this part first!
Thanks
Try to move initialisation code into background queue and only addSubview call on main queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
for (int i = 0; i < imgNumbers.count; i++) {
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect buttonValue = [[btn9Locations objectAtIndex:location] CGRectValue];
myButton.frame = buttonValue;
NSString *imagePart1 = [[NSString alloc] initWithFormat:#"%#", imgNumbers[i]];
[myButton addTarget:self action:#selector(buttonClick:) forControlEvents:UIControlEventTouchDownRepeat];
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [tmpDirURL URLByAppendingPathComponent:imagePart1];
NSString *imageLocation = [[NSString alloc]initWithFormat:#"%#", [fileURL path]];
UIImage * image = [UIImage imageWithContentsOfFile:imageLocation];
[myButton setBackgroundColor:[UIColor colorWithRed:0.94 green:0.39 blue:0.13 alpha:0.0]];
[myButton setBackgroundImage:image forState:UIControlStateNormal];
[myButton setTitle:[imageNames[i] uppercaseString] forState:UIControlStateNormal];
[myButton.titleLabel setFont:[UIFont fontWithName:#"Helvetica-Light" size:20]];
[myButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
[myButton setContentVerticalAlignment:UIControlContentVerticalAlignmentBottom];
[myButton setTitleColor:[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.5] forState:UIControlStateNormal];
myButton.imageView.layer.cornerRadius = 7.0f;
myButton.layer.shadowRadius = 3.0f;
myButton.layer.shadowColor = [UIColor blackColor].CGColor;
myButton.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
myButton.layer.shadowOpacity = 0.5f;
myButton.layer.masksToBounds = NO;
[buttons addObject:myButton];
dispatch_async(dispatch_get_main_queue(), ^{
[scrollview addSubview:myButton];
});
}
});
im running the same piece of code over and over when the user presses a button. If the user presses the button an image appears over the button, if they press it again the image is removed from the buttons subview.
here is my code:
UIImageView *overlay = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"OverlayImage.png"]];
NSString *senderstag = [NSString stringWithFormat:#"%i", buttonFromSender.tag];
if([[dictonaryOfImagesToDelete allKeys] containsObject:senderstag]){
[[buttonFromSender subviews]makeObjectsPerformSelector:#selector(removeFromSuperview)];
}
else{
[buttonFromSender addSubview:overlay];
}
NSString *imageName = [[NSString alloc]init];
imageName = [arrayWithImageNames objectAtIndex:buttonFromSender.tag];
[imagesToDelete addObject:imageName];
[dictonaryOfImagesToDelete setObject:imagesToDelete forKey:[NSString stringWithFormat:#"%i", buttonFromSender.tag]];
Im using a dictionary to keep track of which buttons have been pressed. instead of the imageview over the button being removed, it removes the whole button. How can i get it just to remove the imageview and not the button?
Thanks :D
I have ended up making the UIImageview of the overlay, a UIButton. This allowed to set actions for it. Here is the code that is used:
UIImage *image = [UIImage imageNamed:#"OverlayImage.png"];
UIButton *overlay = [[UIButton alloc]init];
overlay.frame = CGRectMake(0, 0, 100, 150);
[overlay setImage:image forState:UIControlStateNormal];
[overlay addTarget:self action:#selector(removeSelectedImage:) forControlEvents:UIControlEventTouchUpInside];
overlay.tag = buttonFromSender.tag;
[buttonFromSender addSubview:overlay];
NSString *imageName = [[NSString alloc]init];
imageName = [arrayWithImageNames objectAtIndex:buttonFromSender.tag];
[imagesToDelete addObject:imageName];
[dictonaryOfImagesToDelete setObject:imageName forKey:[NSString stringWithFormat:#"%i", buttonFromSender.tag]];
this set up the new UIButton
then to get rid of the UIButton i did this:
-(IBAction)removeSelectedImage:(id)sender{
UIButton *button = (UIButton *)sender;
[button removeFromSuperview];
NSString *tag = [NSString stringWithFormat:#"%i", button.tag];
NSString *deleteWhat = [[NSString alloc]init];
deleteWhat = [dictonaryOfImagesToDelete objectForKey:tag];
[imagesToDelete removeObject:deleteWhat];
[dictonaryOfImagesToDelete removeObjectForKey:tag];
}
If you want to display different image for a button state u can directly initialize the button with to load a picture in that state.
say for example Enabled/Disabled, or Selected/Deselected(normal)
UIButton* myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setImage:[UIImage imageNamed:#"My Image"] forState:UIControlStateNormal];
[myButton setImage:[UIImage imageNamed:#"My Other Image"] forState:UIControlStateSelected];
[myButton setBackgroundImage:[UIImage imageNamed:#"BG Img"] forState:UIControlStateNormal];
References:
Background Image:
http://developer.apple.com/library/IOS/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/occ/instm/UIButton/backgroundImageForState:
Button Image:
http://developer.apple.com/library/IOS/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html#//apple_ref/occ/instm/UIButton/setImage:forState:
I'm new to Objective C. I created the method to construct & display a button inside a UIView (UIView is inside another View named contentView, and contentView to be added as a subview in a UIScrollView. Well the problem is that I cannot click on the generated button to trigger the IB action named playAction. Can someone pls help me? Thanks
- (void) displayCategoryBestSellers
{
//Structure: ScrollView -> ContentView -> MainView -> ImageView and Button
UIView * mainView = [[UIView alloc] initWithFrame:CGRectMake(0,0,160,105)];
mainView.userInteractionEnabled = YES;
UIImage * backgroundImage = [UIImage imageNamed:#"blackwhitesquare.png"];
UIImageView * uiImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,145,105)];
uiImageView.image = backgroundImage;
uiImageView.center = CGPointMake(mainView.frame.size.width /2, mainView.frame.size.height/2);
uiImageView.userInteractionEnabled = YES;
[mainView addSubview:uiImageView];
UIButton *playButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
playButton.frame = CGRectMake(0,0,100,90);
NSData *mydata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://media.theseus.cataloguesolutions.com/images/72by72/324178611_0004_PG_1.jpg"]];
UIImage *myimage = [[UIImage alloc] initWithData:mydata];
[playButton setBackgroundImage:myimage forState:UIControlStateNormal];
playButton.center = CGPointMake(mainView.frame.size.width /2, mainView.frame.size.height/2);
[playButton addTarget:self action:#selector(playAction:) forControlEvents:UIControlEventTouchDown];
playButton.userInteractionEnabled = YES;
[mainView addSubview:playButton];
[contentView addSubview:mainView];
contentView.userInteractionEnabled = YES;
[scrollView addSubview:contentView];
scrollView.delegate = self;
scrollView.userInteractionEnabled = YES;
}
-(IBAction)playAction: (id)sender
{
NSLog(#"Button Clicked");
}
Use UIControlEventTouchUpInside instead of UIControlEventTouchDown.
I have a windowed (e.g. not a full-screen) UIScrollView (inside a UIView) which scrolls through groups of UIImageViews with UIButtons on them (the idea being you click the button to do something with the displayed image). The UIButton does take any touch events - how can I fix it?
I've read this, this, this, this and this - but I either don't understand the answer or its implications, or it's not really relevant.
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
Sentence *testSentence = [[managedObjectContext executeFetchRequest:request error:&error] objectAtIndex:i];
//NSLog(#"testSentence: %#", testSentence);
//NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", i];
//Your going to need to optimise this by creating another thumbnail image to use here.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *imageName = [[paths objectAtIndex:0] stringByAppendingPathComponent:[testSentence image]];
//NSLog(#"imageName: %#", imageName);
UIImage *image = [[UIImage alloc] initWithContentsOfFile:imageName];
//NSLog(#"image: %#", image);
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
//NSLog(#"imageView: %#", imageView);
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[imageView setBackgroundColor:[UIColor blackColor]];
// setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
CGRect rect = imageView.frame;
rect.size.height = kScrollObjHeight;
rect.size.width = kScrollObjWidth;
imageView.frame = rect;
imageView.tag = i; // tag our images for later use when we place them in serial fashion
imageView.frame = rect;
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[aButton setTitle:#"Play" forState:UIControlStateNormal];
aButton.frame = CGRectMake(10, 10, 70, 70);
[aButton setUserInteractionEnabled:YES];
[aButton setEnabled:YES];
[aButton setAlpha:1];
UIView *buttonWrapperUIView = [[UIView alloc] init];
[aButton addTarget:self action:#selector(clickPlay:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:aButton];
[imageView bringSubviewToFront:aButton];
[scrollView1 addSubview:imageView];
NSLog(#"aButton %#", aButton);
[image release];
[imageView release];
}
[self layoutScrollImages]; // now place the photos in serial layout within the scrollview
try
[imageView setUserInteractionEnabled:YES]
Here is the code I'm using:
-(void)viewDidLoad
{
NSString *checkerPath = [[NSBundle mainBundle] pathForResource:#"black-yellow-checker" ofType:#"png"];
UIImage *checkerImage = [[UIImage alloc] initWithContentsOfFile:checkerPath];
checkerView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 230.0f, 320.0f, 280.0f)];
[checkerView setImage:checkerImage];
UIButton *backButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
backButton.frame = CGRectMake(45.0f, 175.0f, 230.0f, 50.0f);
[backButton setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"yellowButton" ofType:#"png"]] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(goBackHome:) forControlEvents:UIControlEventTouchDown];
[backButton setTitle:#"Back" forState:UIControlStateNormal];
backButton.titleLabel.font = [UIFont fontWithName:#"Marker Felt" size:30];
backButton.titleLabel.textColor = [UIColor blackColor];
[checkerView addSubview:backButton];
}
- (void)goBackHome:(id)sender
{
NSLog(#"go back pressed");
}
Not sure why this doesn't work. The button shows up, but when I press it nothing happens. It doesn't even change to the "indented" image when I touch it. Nothing. Can't use IB, has to be programmatically. Any thoughts?
UIImageView has userInteractionEnabled set to NO by default. This prevents any subviews from getting touches.
You could either enable user interaction of the image view by
checkerView.userInteractionEnabled = YES;
or create a new UIView to include both checkerView and the backButton.
UIView* newView = ...
...
[newView addSubview:checkerView];
[newView addSubview:backButton];
I believe that the forControlEvents: has to be UIControlEventTouchUpInside.