Objective C : UIButton not displayed [duplicate] - objective-c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C function calling objective C functions
I've done the following code in ViewController.m
-(void) callIncomingCreateButton
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
button.frame = CGRectMake(100, 170, 100, 30);
//set the button's title
[button setTitle:#"Click Me!" forState:UIControlStateNormal];
//add the button to the view
[self.view addSubview:button];
}
- (IBAction)DemoCall:(id)sender {
callIncoming(1, "a");
}
int callIncoming(int a, char* b)
{
ViewController * tempObj = [[ViewController alloc] init];
[tempObj callIncomingCreateButton];
return a;
}
But still the UIButton is not getting displayed, what am I missing here.
Edit : this is for iOS
and yes, the function does get called. I put a breakpoint and stepped it through.

ViewController * tempObj = [[ViewController alloc] init];
[tempObj callIncomingClass];
It's hard to tell from your example, but assuming that -callIncomingClass is actually part of the definition of ViewController and callIncoming() is called from somewhere else, a likely problem is that tempObj is not the current view controller. You'd need to push tempObj onto the navigation stack, present it modally, or otherwise make it the active view controller in order for its view to be loaded. If its view isn't loaded, then there's no view to add the button to, and even if it has a view, that view won't be in the window.

Related

UIButton not being added to custom UIView Objective C

I am creating a custom UIView called DropDown that contains a button. In the .h file I initialize the button and in the constructor of the UIView, I add it to the frame and set the title. Here is the constructor:
-(id) initWithFrame:(CGRect)frame title1:(NSString*)text1{
self = [super initWithFrame:frame];
if (self){
_button1 = [UIButton buttonWithType:UIButtonTypeCustom];
[_button1 setTitle:text1 forState:UIControlStateNormal];
_button1.frame = CGRectMake(10, 10, 50, 20);
[self addSubview:_button1];
}
return self;
}
In my ViewController viewDidLoad I am instantiating a DropDown object as follows:
_dropDown = [[DropDown alloc] initWithFrame:_dropDown.frame title1:#"Title"];
The _dropDown object is an IBOutlet and I hook it up on the view controller. When I run the application, no button is shown and I am unsure why. Any help would be much appreciated.
This statement
_dropDown = [[DropDown alloc] initWithFrame:_dropDown.frame title1:#"Title"];
references _dropDown.frame which is nil at this point because _dropDown hasn't been assigned yet. I would suggest creating the frame explicitly more like this:
_dropDown = [[DropDown alloc] initWithFrame:CGRectMake(10, 10, 50, 20) title1:#"Title"];
(you'll need to figure out the sizing for CGRectMake)

Cycling through Image Array within Object in Time Intervals (Objective-C)

My general question is how do you have an object with an image array:
#import <Foundation/Foundation.h>
#interface Object: NSObject {
UIImage *image[imageNumber];
}
And then take these images and apply them to a button in a different class, starting with imageArray[0] and every few seconds changing it to imageArray[1], etc, but stopping the loop at the last image.
What I specifically did was create a Plant object:
#import <Foundation/Foundation.h>
#interface Plant : NSObject {
UIImage *plantImage[3];
int imageNumber; //to specify which image to display, increments with timer
NSTimer *plantImageTimer;
}
and declared then made a few methods like
-(void)addPlantImages:(UIImage *) firstImage withPlantImage2:(UIImage *) secondImage withPlantImage3:(UIImage *) thirdImage{
plantImage[0] = firstImage;
plantImage[1] = secondImage;
plantImage[2] = thirdImage;
}
//this makes the Plant into a button
-(void)createPlantButtonForPlant:(Plant *) plantType forView:(UIView *) view withButtonRect:(CGRect) buttonRect{
imageNumber=0;
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = buttonRect;
button.hidden = NO;
[view addSubview:button];
[plantType growPlant:button]; //explained in code below
}
And from here I don't know what to do anymore.
I tried using an NSTimer, but you can't put parameters into the selector, so I can't specify which button (or Plant) I want to cycle images through.
Extra tidbits of code in Plant that I have (which do not work); I'm using NSTimer userinfo incorrectly, but I don't understand how to use it, to be honest.
-(void)growPlant:(UIButton *) button{
plantImageTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(changePlantImage:) userInfo:button repeats:YES];
}
-(void)changePlantImage: (UIButton *) plantButton{
if(imageNumber == 3){
[plantImageTimer invalidate];
} else {
[plantButton setImage:plantImage[imageNumber] forState:UIControlStateNormal];
imageNumber++;
}
}
I imported Plant into my view controller (called PracticeViewController) and tried to make it so that when I clicked a button, a Plant button popped up and cycled through the images.
(void)buttonAction{
theButton.hidden = YES; //I did make this button, just didn't add the code here. Declared in header.
CGRect imageViewRect = CGRectMake(100, 100, 100, 100);
Plant *testPlant = [Plant new];
[testPlant addPlantImages:[UIImage imageNamed:#"plant2.png"] withPlantImage2:[UIImage imageNamed:#"plant2.png"] withPlantImage3:[UIImage imageNamed:#"plant2.png"];
[testPlant createButtonForPlant:testPlant forView:self.view withButtonRect:imageViewRect];
}
If you need more code or other information, just comment below and I will reply asap.
Now that I've done more programming, I realize how complicated I made this code lol. Anyway, all I would have had to do was add
[button addTarget:self action:#selector(changePlantImage) forControlEvents:UIControlEventTouchUpInside];
after making the button instance. This would then scroll through whichever images the plant had in its array.

Specific action for each buttons in UIScrollView

I have an UIScrollView page . On this UIscrollView I have different images inside buttons you can see it in below code, and I want to load this images in UIWebView when I press the buttons, My question is how can I know which button are click. Would you please give me some hint for implementing this?
I'm new to objective-C
Here is my action: I want to have one action for each images, rightnow I have just one action for all images, I one to have one for each image
- (IBAction)openAction:(id)sender {
NSLog(#"test");
}
The actual button is passed to the IBAction. Setting a tag on the button is one way of doing it. If you created outlets for all your buttons in Interface Builder, you can simply do something like this:
- (IBAction)openAction:(id)sender {
UIButton *b = (UIButton *)sender;
if ([b isEqual:self.outletButton1]) {
// Do something with button 1
}
else if ([b isEqual:self.outletButton2]) {
// Do something with button 2
}
}
Don't use Same Tag for Button. Use Different Tag for different button.
For ex [btn setTag:1] .
you can use [btn setTag:i];
Dynamic value
Give each button a unique tag, in your code or in Interface Builder.
Then in your action you can do:
- (IBAction)openAction:(id)sender {
UIButton *b = (UIButton *)sender;
NSLog(#"button %d is pressed", b.tag);
}
I see that you already give your imageviews tags. Those are not buttons! You should instead create UIButtons whose content are images. See UIButton's setImage:forState:
Edit: In response to your question below, here's an example:
NSMutableArray *bArray = [NSMutableArray arrayWithCapacity:kNumImages];
NSUInteger i;
for (i = 1; i <= kNumImages; i++)
{
NSString *imageName = [NSString stringWithFormat:#"image%d.jpg", i];
UIButton *btn = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
btn setImage:imageName forState:UIControlStateNormal];
btn.tag = 100+i;
[bArray addObject:btn];
}
You don't have to add UIButton over UIImageView. Instead, you can set the image for UIButton like this.
[btn setImage:[UIImage imageNamed:#"image1"] forState:UIControlStateNormal];
You can access the image in the action like this:
- (IBAction)openAction:(id)sender {
if([[btn currentImage] isEqual:[UIImage imageNamed:#"image1"]]){
}
NSLog(#"test");
}

How to have a UIKit button open another view?

I have a grid of buttons in one page. I want the buttons to lead to another view when clicked. What should I add to the following action to change the view?
-(void)buttonPressed:(UIButton *)button {
NSLog(#"button %u -- frame: %#", button.tag, NSStringFromCGRect(button.frame));
}
The grid of buttons is created with:
{
int rows = 13, columns = 4;
UIView *buttonView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, 80*columns, 32*rows)];
int currentTag = 0;
for (int y = 0; y < rows; y++) {
for (int x = 0; x < columns; x++) {
UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
// [button.layer setBorderWidth:1.0];
// [button.layer setBorderColor:UIColor blackColor]];
button.backgroundColor=[UIColor colorWithRed: 201.0/255.0 green: 201.0/255.0 blue:201.0/255.0 alpha: 1.0];
button.tag = currentTag;
currentTag++;
[button.layer setBorderColor: [[UIColor blackColor] CGColor]];
[button.layer setBorderWidth: 1.0];
[button setTitle:[NSString stringWithFormat:#"%d",currentTag] forState:UIControlStateNormal];
button.frame = CGRectMake(80*x, 32*y, 80, 32);
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[buttonView addSubview: button];
}
}
// Center the view which contains your buttons
CGPoint centerPoint = buttonView.center;
centerPoint.x = self.view.center.x;
buttonView.center = centerPoint;
[self.view addSubview:buttonView];
}
Maybe you want to connect an action?
[button addTarget:self
selector:#selector(buttonPressed:)
forControlEvents:UIControlEventTouchUpInside];
(check syntax, this is by memory...)
Rinju's answer would work, but it needs a little more explanation. I'm not sure why exactly you would like to create this grid of buttons (more info would be nice), but if you want each button to show a new view, then tags are important!
If you want to open the same view, but with different properties shown on that view, you'd need to create a new view controller class. Let's call this DetailViewController.
Now, in your buttonPressed: method, you're going to need to instantiate this view controller and set a property of it!
#interface DetailViewController : UIViewController
#property (nonatomic, assign) int buttonTag;
...
//other methods, properties, etc. here
...
#end
Now, in your view controller where the buttons are, you can do this (for the sake of simplicity, I will assume you are using storyboards. If not, it can still be easily accomplished similar to what Rinju has done).
-(void)buttonPressed:(UIButton*)button {
[self performSegueWithIdentifier:#"DetailView" sender:button];
}
Now, you can implement the prepareForSegue method, which is called just before the segue fires:
-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender {
if( [[segue identifier] isEqualToString:#"DetailView"] ) {
DetailViewController *detailView = [segue destinationViewController];
detailView.buttonTag = ((UIButton*)sender).tag;
}
}
Now that the tag is set for your new detail view controller, you can probably use switch statements (or better yet, a model object which is passed this buttonTag) in viewDidLoad: of the DetailViewController to set up the UI there. Basically what we are doing is using the tag of the button to distinguish which button was pressed, and based on this create a new view!
What you may want to do is create a typedef enum structure to make names for the tags instead of using raw integers. This will increase the readability of your code, and also will help you in not getting confused ;)
-(void)buttonPressed:(UIButton *)button
{
NSLog(#"button %u -- frame: %#", button.tag, NSStringFromCGRect(button.frame));
Cart *crtObj=[[Cart alloc]initWithNibName:#"Cart" bundle:nil];
[self.navigationController pushViewController:crtObj animated:YES];
[crtObj release];
}

creating an infinite stack of UIImageviews in xcode [duplicate]

This question already has answers here:
Why can't variables be declared in a switch statement?
(23 answers)
Closed 2 years ago.
i am trying to create a stack of UIImageViews in my app where i can indefinitely touch the uiimageview move it around the screen and drop it anywhere and there would still be a representation of the UIImageview in the original location where i could go grab another uiimageview move it and so on.the way i was trying to solve this problem was to create a uiimageview in IB that would remain in its original location and each time a touch is detected on top of it create a new uiimageview in the same location that would be able to be moved. here is the code i have so far:
-(void)dispatchTouchEvent:(UIView *)theView toPosition:(CGPoint)position
{
switch (glyphActive) {
case 1:
UIImage *image = [UIImage imageNamed:#"1.png"];
onePieceCopy = [[UIImage alloc] initWithImage:image];
onePieceCopy.frame = CGRectMake(currentPos.x, currentPos.y, 75, 75);
[self.view addSubview:image];
if (CGRectContainsPoint([onePiece frame], position)) {
onePiece.center = position;
[self bringSubviewToFront:onePiece];
}
//[onePieceCopy release];
break;
}
}
however i am getting errors on this line:
UIImage *image = [UIImage imageNamed:#"1.png"];
that says "expected expression before 'UIImage'".
and another error here:
[self.view addSubview:image];
that says " error: request for member 'view' in something not a structure or union"
i'm fairly new to all this and im not sure what im doing wrong can anyone give me a hand?
well for one thing [self.view addSubview:image] should be [theView addSubview:image]