How to set picture for uibutton when accessing it as subview - iphone

So i have a button in a view i know how to access it but i have no idea how to change picture on that button. Here is what i got:
for(UIView *button in [okvir subviews]){
if([button isKindOfClass:[UIButton class]]){
UIImage *picture=[UIImage imageWithData:slika];
[button setImage:picture forState:UIControlStateNormal];
}
}
However that results in a error:
No visible #interface for 'UIView' declares the selector 'setImage:forState:'
I'm guessing that's because button is UIView not UIButton, any idea how to do that?

You need to cast your pointer so that the compiler recognizes it as being a UIButton and not a generic UIView. This is entirely safe since you are checking the runtime type of your pointed object, so you can be sure it is a UIButton.
Use this:
[(UIButton*)button setImage:picture forState:UIControlStateNormal];

Related

UIButtons not working on programmatically created UIView

I have a UIViewController which I want to display a UIView that renders as a menu. This menu will have several buttons on it. I wanted to reuse this menu a few different places in my app so I figured I would create a class called ViewFactory that has a method that returns a UIView with these buttons.
On my ViewController I call this method and get the returned UIView and add it as a subview.
This works just fine. I can see the view and all its buttons, however, the buttons do not respond to any touch events. Not sure why this is the case and curious to know what I am doing wrong.
Here is my code for the ViewFactoryClass:
- (UIView *) addCloseRow
{
// UIView container for everything else.
UIView *navRow = [[UIView alloc] initWithFrame:CGRectMake(0,225,350,45)];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.userInteractionEnabled = YES;
[navRow addSubview:button];
[button addTarget:self action:#selector(closeButtonTouchDownEvent) forControlEvents: UIControlEventTouchDown];
navRow.userInteractionEnabled = YES;
return navRow;
}
In my main NavigationController class here is how I am calling and getting the UIView:
ViewFactory *factory = [[ViewFactory alloc] init];
[self.navigationController.navigationBar addSubview:[factory MainNavigationUIView]];
Again, the UIView shows up but the buttons never respond to anything.
You added the button with target and selector for ViewFactoryClass
And now you are creating instance and trying to call an action from ViewFactory class.
You can change the method to something like this:
- (UIView *) addCloseRow : (id)object {
...
[button addTarget:[object class] action:#selector(closeButtonTouchDownEvent) forControlEvents: UIControlEventTouchDown];
...
}

Custom UIButton's action does not called

I have subclass of UIButton:
#interface MyButton : UIButton
- (IBAction) buttonPressed:(id)sender;
#end
#implementation MyButton
- (void)awakeFromNib
{
NSLog(#"awake from nib");
}
- (IBAction) buttonPressed:(id)sender
{
NSLog(#"button pressed");
}
#end
I add a button in my parent xib, set it's class to MyButton, and connected it's action to First Responder's method buttonPressed.
When I start an application and load my parent xib with my button inside, than awakeFromNib from MyButton class is called. But when I press the button, nothing happens. I was expecting that my method buttonPressed from MyButton class will be called.
I supposed, that my button's view is the first responder in responder chain, but apparently I do something wrong.
Could you please suggest something?
If you want that your button always call the method declared add the code above to the awakeFromNib method
[self addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
and later when you added it to a view controller do not assign it a new action, this way it will always call your method.
Depending on what you are doing with the button - there is no real need to make a subclass.
Here is some code how to make a simple button that triggers a method:
UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[myButton setFrame:CGRectMake(10, 10, 100, 30)];
[myButton setTitle:#"Title" forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(myMethod:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:myButton];
the add target bit tells the button to trigger the given selector when the user touches up inside the button (taps it). The target is the object that the selector is in.
Hope this helps, you should not need to subclass UIButton unless you have custom layouts or specific custom functionality for it.
Since you want to handle the action from the button code itself, you may have to override this method - (void)sendActionsForControlEvents:(UIControlEvents)controlEvents and handle your event as if it was sent to your button;

How to handle a UIView's control events from a UIViewController.

I have subclassed a UIView. I am adding it as a subview of a UIViewController view. I have a button in the UIView. What I want is to handle the button click inside my UIViewController, where I will remove the UIView from superview and push another UIViewController. How can I do this.
You must attach the target with your UIButton. addTarget method is used for getting the event when you click on button and defined in UIControl class which is direct super class of UIButton
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
Code to receive the event for Button touch.
[myButton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
Implementation for the action.
-(void) buttonClicked:(id) sender {
UIButton* myButton = (UIButton*)sender;
//Put your code here
}

added button to uitableviewcell not responding

I have created a custom tableviewcell through interface builder with a label and a button. In the .h and .m file I have made outlets and actions for the button which I have connected.
This cell is added to a tableview controlled by a uiviewcontroller class. However my problem is that when I tap the button, the button is not activated, however I am pushed on to the detailed view belonging to the cell. It seems like the button is behind the cell.
Any suggestions for what I have forgotten or should change?
I have created a button programatically and added as subview to the cell instead and this works, however this gives me another problem as the button is added everytime a cell is loaded.
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(200.0f, 5.0f, 100.0f, 40.0f)];
//Set image
UIImage *img = [UIImage imageNamed:#"myPackage.png"];
[button setImage:img forState:UIControlStateNormal];
[img release];
[button addTarget:self action:#selector(myPackagePushed:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button];
I would really like to use the interface builder approach - any suggestions?
Regards
try
[cell.contentView addSubview:button];
also
UIImage *img = [UIImage imageNamed:#"myPackage.png"]; here you are not allocating memory so no need for
[img release]; because there is a possibility of crash
The button should fire the IBAction method that you have set in IB. Have you checked by inserting an NSLog or by setting a breakpoint if the method is entered?
Is the button set to be initially activated in IB?
The crux with the IB construction is that the IBOutlet gets its value when the cell is loaded from the xib. The IBOutlet will then be the button in the cell that the tableview happend to load last.
WHen you add the button programatically, you might need to have the previous added button to removeFromSuperview before you add a button again to that cell.
In my case, the problem was that the button was a subview of the background view.
Buttons assigned to the background view apparently can't respond to touches.

How to remove a subview if triggered from one of its components?

I'm looking for a smart way to remove a subview (with removeFromSuperview) when the subview itself (or precisely said one of its components) triggered the removal. As for the source code this would be like
UIView * sub_view = [[[UIView alloc] initWith...
UIButton *button = [UIButton buttonWithType...
[sub_view addSubview:button];
[self.view addSubview:sub_view];
If the button have now something like
[button addTarget:self action:#selector(closeMySubview) forControlEvents:UIControlEventTouchUpInside];
the call to removeFromSuperview inside closeMySubview does not work but results in SIGABRT and unrecognized selector sent to instance ... . Well that there is something not more present anymore is not a surprise but what would be the right way?
(Removing the subview if triggered from an another gui component would work of cause but is not the point here.)
The best pattern for this type of action is the "delegate" pattern.
You can subclass anything and add this property:
#property (assign) id delegate;
for the instance variable:
id delegate;
Also, define a protocol like this:
#protocol MySubViewDelegate
-(void)myViewDidFinish:(UIView *)view;
So in your view controller, you can instantiate the subview, tell it your its delegate, and add it to the view. Then, an action on the subview calls the method:
[delegate myViewDidFinish:self];
The viewcontroller then can say something like:
[view removeFromSuperView];
It should work.
Check if your sub-view points to an existing view.
Post the entire code of the initiation and the removeFromSuperview.