IOS 5 block unrecognized selector - ios5

I am trying to assign a block to a button object so that each time a button is pressed the block will execute. I have the following defined button subclass that holds the block for each unique button I create.
typedef void (^ButtonPressBlock)();
#interface PhotoButton : UIButton
{
ButtonPressBlock photoButtonPressed;
}
#property (copy) ButtonPressBlock photoButtonPressed;
#end
There is a #synthesize photoButtonPressed in the .m
In a separate UIViewController I #import "PhotoButton.h" and then in that view controller I have a method that creates the buttons. The code looks like this.
PhotoButton* photoButton = [UIButton buttonWithType:UIButtonTypeCustom];
photoButton.frame = CGRectMake(i, j, thumbSize+2, thumbSize+2);
[photoButton setImage:photoThumb forState:UIControlStateNormal];
[photoButton setAdjustsImageWhenHighlighted:NO];
[photoButton setPhotoButtonPressed:^()
{
[self performSegueWithIdentifier:#"photoSegue" sender:aPhoto];
}];
assigning the block to the photoButton fails at execution with a
-[UIButton setPhotoButtonPressed:]: unrecognized selector sent to instance...
Not sure what I am doing wrong as blocks are new to me. I thought this would be a great way to make a thumbnail image responsive to a touch and then segue to the full sized image in another view controller. Now I'm not sure.

This:
PhotoButton* photoButton = [UIButton buttonWithType:UIButtonTypeCustom];
should be:
PhotoButton* photoButton = [PhotoButton buttonWithType:UIButtonTypeCustom];
You were creating an instance of UIButton, not PhotoButton

Related

Creating an UIImageView on UIButton click

I have a button setup in one class and on clicking it, I am calling a method which is in another class and in that method I have setup code for UIImageView.
the method is getting called, But somehow the ImageView doesnt seems to get created, I dont understand why, And therefore I cannot add any Image to that ImageView.
Here's some code of what I am trying to do:
In my first viewControllerClass I have this method which fires on a button click:
- (IBAction)buttonClicked:(id)sender {
[secondViewController createNewImageView];
}
and then in the second viewController I am calling that createNewImageView method, in which I am creating an ImageView at runtime:
-(void)createNewImageView {
newImageView = [[UIImageView alloc] initWithFrame:CGRectMake(100,100, 100, 100)];
newImageView.backgroundColor = [[UIColor yellowColor] colorWithAlphaComponent:0.4];
[self.otherNewView addSubview:newImageView];
}
But somehow the ImageView is not getting added on my view, Any Ideas why this is happening ?
What am i missing here ..?
Thanks for your time :)
EDIT : The class which holds the button is UIPopOverController.
Have you allocated secondViewController before doing,
[secondViewController createNewImageView];
I think you have not created an object for secondViewController.
So before calling the function create the object for the class.

Calling to function from UIBarButtonItem

I have button in my view with a setAction to a local function.
in GameOptions.m i have the next function:
- (void) changeSettings (UIBarButtonItem *) sender {
// do something
}
and a button that start it in GameOptions.m :
[btn1 addTarget:self action:#selector(changeSettings:) forControlEvents:UIControlEventTouchUpInside];
now i moved it from his view to a navigation controller as an rightBrButtonItem.
the myVC is an instance of small UIViewController with all the navigationBar settings,and each time i using pop ,push to it .
UIBarButtonItem *buttonNav1 = [[UIBarButtonItem alloc] initWithCustomView:settingsView];
[myVC.navigationItem setRightBarButtonItem:buttonNav1];
the problem is that this button is not in his GameOptions class and i want it to start the same function with implementation in GameOptions.m.
I would like to do the next thing :
buttonNav1 setAction:changeSettings;
but its impossible, the changeSetting is not recognized...
Tried : buttonNav1.action = self. but i'm not getting this function, only functions without parameters.
How can i call to chnageSettings from that button in navigationBar
All you need to do is inform your UIBarButtonItem of the existence of the GameOptions object.
That's what you were doing using self in :
[btn1 addTarget:self action:#selector(changeSettings:) forControlEvents:UIControlEventTouchUpInside];
Just after instanciating your UIBarButtonItem *buttonNav1, you can send it the message addTarget:action:forControlEvents: or, if you want to use setAction, don't forget to also use setTarget.
So now, your question is: what is the most elegant/efficient way to pass the GameOptions object's pointer to the UIBarButtonItem ;)

Really weird "[UIAccessibilityBundle setWhatever:]: unrecognized selector sent to instance 0xnnnnnnn"

So, I'm puzzled by a really weird crash occurring in my app.
Background: I have a class CustomButton overriding UIButton. Briefly, the interface looks like:
#interface CustomButton : UIButton
#property (nonatomic, getter = isLoading) BOOL loading;
#end
Implementation:
#implementation CustomButton
#synthesize loading = loading_;
- (id)init {
if ((self = [UIButton buttonWithType:UIButtonTypeCustom])) {
[self setTitle:NSLocalizedString(#"My Button", nil) forState:UIControlStateNormal];
[[self titleLabel] setShadowColor:[UIColor blackColor]];
[[self titleLabel] setShadowOffset:CGSizeMake(0, -1)];
[self setContentEdgeInsets:UIEdgeInsetsMake(0, 77, 0, 30)];
UIImage *backgroundImage = [[UIImage imageNamed:#"back.png"] stretchableImageWithLeftCapWidth:77 topCapHeight:0];
UIImage *highlightedBackgroundImage = [[UIImage imageNamed:#"back_highlighted.png"] stretchableImageWithLeftCapWidth:77 topCapHeight:0];
[self setBackgroundImage:backgroundImage forState:UIControlStateNormal];
[self setBackgroundImage:highlightedBackgroundImage forState:UIControlStateHighlighted];
[self sizeToFit];
}
return self;
}
- (void)setLoading:(BOOL)loading {
if (loading_ != loading) {
// Do fancy things
}
}
#end
Problem: I'm trying to use the button in a class, so I have property and so on:
...
#property(nonatomic, strong) CustomButton *customButton;
...
#syntesize customButton = customButton_;
...
- (void)aMethod {
self.customButton.loading = YES;
}
...
The button, of course, is initialized.
Then, upon executing the statement self.bookButton.loading = YES, I get this error
2012-08-28 12:54:25.091 MyApp[9465:15803] -[UIAccessibilityBundle
setLoading:]: unrecognized selector sent to instance 0x8650cc0
2012-08-28 12:54:25.091 MyApp[9465:15803] *** Terminating app due
to uncaught exception 'NSInvalidArgumentException', reason:
'-[UIAccessibilityBundle setLoading:]: unrecognized selector sent to
instance 0x8650cc0'
*** First throw call stack: (0x1ead022 0x203ecd6 0x1eaecbd 0x1e13ed0 0x1e13cb2 0x26bf5 0x257ce 0xfa938f 0xfa96a4 0xfa99a7 0xfb8aea
0x11600be 0x11603c7 0x1160436 0xf10e49 0xf10f34 0xc5bcaac 0xe04b54
0x272e509 0x1de4803 0x1de3d84 0x1de3c9b 0x27887d8 0x278888a 0xee0626
0x14cce 0x27b5 0x1) terminate called throwing an exception
I honestly have no idea about what to look for. It's either something really really stupid, or something really subdle.
I've been searching on google/stackoverflow already of course, but I didn't manage to get an answer.
Usually that error occurs, as far as I know, when the object doesn't "understand" the sent message, but this shouldn't be the case. I don't even get a warning from the compiler.
If you have even just an idea of what I could look for or you want more details, let me know, thanks.
EDIT: forgot to specify that I am using ARC.
UPDATE: In the answers below Phillip Mills said that it might have been a premature memory release issue. It's a good point, but Instrument didn't find any zombie. Moreover, I've put a log right before the crashy statement, where I try print information about the CustomButton object and few things related to a UIButton, like the title. Everything looks ok. The title is the one I've set, the frame is there and so on... so I believe the object (an actual UIButton) exists and it's also the expected one. The only thing is the "loading" property that messes everything up.
SOLUTION: the init method was the source of the problem. Instead of initializing an instance of the subclass of the button, it was initializing an instance of UIButton. So, conequentely, no "loading" properties could be found. Substituting init with initWithFrame and using the standard procedure to override the initializer, everything works great.
Still a mistery, though, the reason why I got UIAccessibilityBundle as the origin of the error and not a UIButton.
Are you casting anything to (CustomButton *) in your app? Double-check the casts - you might be incorrectly casting something that's not a CustomButton and storing the result in the customButton property.
The button is almost certainly being released prematurely and having its address re-used for a UIAccessibilityBundle object. Try turning on zombies (or run Instruments to look for zombies) and you should see better information if the memory management problem isn't obvious.
Try
#interface CustomButton : UIButton
#property (nonatomic, assign) BOOL loading;
#end
and
#implementation CustomButton
#synthesize loading = _loading;
- (id)init {
....
}
- (void)setLoading:(BOOL)loading {
if (self.loading != loading) {
// Do fancy things
}
}
#end
For all other instances of loading, use self.loading.
Without seeing the other parts of your code, this is my best guess.

how to change uibutton title at runtime in objective c?

I know this question is asked many a times,and i am also implementing the same funda for chanding the title of the uibutton i guess.
Let me clarify my problem first. I have one uibutton named btnType, on clicking of what one picker pops up and after selecting one value,i am hitting done button to hide the picker and at the same time i am changing the the title of the uibutton with code
[btnType setTitle:btnTitle forState:UIControlEventTouchUpInside];
[btnType setTitleColor:[UIColor redColor] forState:UIControlEventAllEvents];
But with my surpriaze,it is not changed and application crashes with signal EXC_BAD_ACCESS. I am not getting where i am making mistake.I have allocated memory to the btnType at viewdidLoad. Also I am using
-(IBAction)pressAddType
{
toolBar.hidden = FALSE;
dateTypePicker.hidden = FALSE;
}
event on pressing the button to open the picker. Also i would like to mention that i have made connection with IB with event TouchUpInside for pressAddType.
Any guesses? I will be grateful if you could help me.
Thanks.
UPDATE:
#interface AddSettingPage : UIViewController<UITextFieldDelegate>
{
IBOutlet UIButton *btnType;
NSString *btnTitle;
}
#property (nonatomic, retain) IBOutlet UIButton *btnType;
-(IBAction)pressAddType;//:(id)sender;
Also
#synthesize btnType,btnTitle;
try
[yourButton setTitle:#"your title" forState:UIControlStateNormal];
[yourButton setTitle:#"your title" forState:UIControlStateSelected];
[yourButton setTitle:#"your title" forState:UIControlStateHighlighted];
when the picker is dismissed, the button (which was the control that hold focus) will be in the selected state (or the highlighted .. check it out).
and stop using UIControlEventTouchUpInside in the forState: parameter. it is not a state, it is an event. you are passing an event identifier instead of a state identifier
The state you pass in setTitle should be something like UIControlStateNormal:
[b setTitle:#"" forState:UIControlStateNormal];
Instead of
- (IBAction) pressAddType;
declare
- (IBAction) pressAddType:(id)sender; //or (UIButton *)sender
and define it like:
-(IBAction)pressAddType:(id)sender
{
toolBar.hidden = FALSE;
dateTypePicker.hidden = FALSE;
[(UIButton *)sender setTitle:btnTitle forState:UIControlEventTouchUpInside];
[(UIButton *)sender setTitleColor:[UIColor redColor] forState:UIControlEventAllEvents];
}
As you can see, you don't need to have your button as an ivar because it is passed as a parameter of the method when pressed.
This answer why not button title change only,EXC_BAD_ACCESS error only you getting when an object you trying to access those object is not in memory of stack or that object has null value. So my advice is please check your object (btnTitle) is in memory or not?

2D Array of UIButtons Isn't Working (Objective-C/iPhone development)

I've made a bunch of UIButtons in a grid and I want to be able to iterate over them easily so I've put them in an NSMutableArray.
Like so:
// in .h
UIButton* button1;
UIButton* button2;
...
UIButton* button9;
UIButton* myButtons[3][3];
// in init function in app
myButtons[0][0] = button1;
myButtons[0][1] = button2;
...
myButtons[2][2] = button9;
But now if I try to access the title of a button in myButtons I get nil:
// elsewhere in app
[button1 setTitle:#"A" forState:UIControlStateNormal];
// and then:
NSLog(#"currentTitle of button1: %#", (myButtons[0][0]).currentTitle); // -> (null)
Anybody know what's going on? Thanks!
first of all, that's not an NSMutableArray, it's just a plain ol' array.
Second, where do you set button1 to a non-null value? Is it before or after assigning myButtons[0][0] = button1;? I would check and make sure that myButtons[0][0] is non-null when calling the NSLog method. If it is, then you need to assign your array later or assign the buttons earlier.