Get return values between these 2 classes - iphone

below is part of my code that I'm working on for quick reply on iOS 5, what i want to know is how to get the return values from the 3 methods under SBBulletinBannerItem to show up in the title and message fields accordingly, after i get this sorted out, I'm going to use the _appName return value to tell the gesture to open the quick reply alert if its sms, or to open the app if its anything else, I've tried quite a bit of things and can't seem to get it to work, thank you
%hook SBBulletinBannerController
- (void)_handleBannerTapGesture:(id)qreply
{
qreply = [[UIAlertView alloc] initWithTitle:#"title" message:#"message" delegate:self cancelButtonTitle:#"Close" otherButtonTitles:#"Reply", nil];
[qreply show];
[qreply release];
}
%end
%hook SBBulletinBannerItem
- (id)_appName { return %orig; }
- (id)title { return %orig; }
- (id)message { return %orig; }
%end

Related

How get return value of the RacSignal to

I have a beginner's question regarding the ReactiveCocoa.
I want to return the value of shouldPerformSegueWithIdentifier method based on user interaction with UIAlertView.
That's what I have so far, obviously it doesn't work. How should I proceed?
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
if([identifier isEqualToString:ModalBrowser]){
if(self.delegate.currentCoreConversation!=nil){
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Disconnect?" message:#"This action will disconnect you from your current conversation. Would you like to continue?" delegate:self cancelButtonTitle:#"Heck No Techno!" otherButtonTitles:#"Certainly", nil];
[alertView show];
[alertView.rac_buttonClickedSignal subscribeNext:^(NSNumber *x) {
// return [x isEqual:#1];
}];
[alertView.rac_buttonClickedSignal subscribeNext:^(NSNumber *x) {
// return [x isEqual:#1];
}];
}
}
return YES;
}
Alert views don't block the thread of execution when displayed. In other words, the user's tap will arrive after you've already returned from -shouldPerformSegueWithIdentifier:sender:.
Instead of trying to figure out a way to change that behavior, you should return NO immediately, and then programmatically trigger a segue later (after the user has responded to your alert view).

Why doesn't the UIAlertView work?

I am testing this piece of code but when I run it, it does not trigger the UIAlertView. When the code hits If (ongoingGame = YES) and NSLog it jumps directly to the 'otherButtonTitles:nil' without executing the UIAlertView.
Can someone please explain to me why it does not trigger it?
-(IBAction)continueGame_button:(id)sender {
//=====CHECK IF THERE IS AN ON-GOING GAME, IF SO CONTINUE=====//
AccessCurrentGameData *isThereAnOngoingGameFunction = [AccessCurrentGameData new];
BOOL ongoingGame = [isThereAnOngoingGameFunction checkIfGameOngoing];
[isThereAnOngoingGameFunction release];
NSLog(#"+ + +continueGame_button+ + +");
NSLog(#"ongoingGame = %#\n", (ongoingGame ? #"YES" : #"NO"));
if (ongoingGame == YES) {
NSLog(#"++++++++++++++++++");
NSLog(#"++++++++++++++++++");
NSLog(#"++++++++++++++++++");
NSLog(#"++++++++++++++++++");
NSLog(#"++++++++++++++++++");
//
UIAlertView *continueGame = [[UIAlertView alloc] initWithTitle:#"Fortsätta spel"
message:#"Det finns ett aktivt spel, klicka Spela eller Tillbaka"
delegate:self
cancelButtonTitle:#"Tillbaka"
otherButtonTitles:nil];
[continueGame show];
[continueGame release];
}
exit(0);
}
You are assigning onGoingGame to YES, not comparing it to YES. Use == instead of =.
Your alert code is just fine I use that form (three lines - init, show, release) all of the time to do alerts.
I suggest that the exit(0) is the root of the problem. If you want to exit after the user closes the alert, you should assign a delegate which will close the app when the user taps on the close button. Use your code, but remove the exit(0). Then implement the UIAlertViewDelegate as follows:
-(IBAction)continueGame_button:(id)sender {
//=====CHECK IF THERE IS AN ON-GOING GAME, IF SO CONTINUE=====//
AccessCurrentGameData *isThereAnOngoingGameFunction = [AccessCurrentGameData new];
BOOL ongoingGame = [isThereAnOngoingGameFunction checkIfGameOngoing];
[isThereAnOngoingGameFunction release];
NSLog(#"+ + +continueGame_button+ + +");
NSLog(#"ongoingGame = %#\n", (ongoingGame ? #"YES" : #"NO"));
if (ongoingGame == YES) {
NSLog(#"+++++++++ ONGOING GAME +++++++++");
//
UIAlertView *continueGame = [[UIAlertView alloc] initWithTitle:#"Fortsätta spel"
message:#"Det finns ett aktivt spel, klicka Spela eller Tillbaka"
delegate:self
cancelButtonTitle:#"Tillbaka"
otherButtonTitles:nil];
[continueGame show];
[continueGame release];
}
}
- (void) alertViewCancel:(UIAlertView *)alertView{
//If you have other alerts, you may want to check the title of the alert to
//make sure that you only exit when THIS alert is dismissed
exit(0);
}
Dont' forget to add the <UIAlertViewDelegate> code to your header (.h) file.
You can also use - (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex, if you want multiple buttons, with one of them being a specific "Quit" button.
Please note that Apple discourages using exit() in apps that are released to the App Store, and using it might get your app rejected.
You can try this line instead.
[[[[UIAlertView alloc] initWithTitle:#"this is my message" message:nil delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil] autorelease] show];
Also, I believe Apple does not advice using exit() within your application. They always want the user to use the "Home" button to exit an app. The exit() call is a hard exit and this might be the reason you are not seeing the Alert.
You should not release it immediately. And you exit the app even before the alert view gets a chance to display itself. :)
Your code will continue to run even when the alert view is visible.
Fixage
Remove the exit call
Don't release the alertview. Release it in it's owner's dealloc method.
Make the alert view an instance variable and add a retain property to it.
Initialize the alertview in its getter if it's not yet available.
Set it's attributes in the IBAction and show it.
Add the appropriate delegate methods.
If I wasn't writing this answer on an iPod touch I'd post some example code. You can find lots of such code with Google.
Also, if your app isn't English-only you should always use localization provided by Foundation. Otherwise you can get English text with default error messages and other UI elements.

UIAlertView not displaying complete message

I have the following function to display error messages to user. But it does not seem to show the complete message. It will display upto certain characters followed by ....
How can I make it show the entire message?
(void) showAlert:(NSString*)title forMessage:(NSString*) body
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:title message:body delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
}
There is a way.
When you present your alert, you can just implement this method:
- (void)willPresentAlertView:(UIAlertView *)alertView {
alertView.frame = CGRectMake(alertView.frame.origin.x, alertView.frame.origin.y -50
,alertView.frame.size.width, 300);
}
Adjust the height to fit your need. It will look something like this:
If you need to move the button around, you can just add new lines (\n) to your message, and it will move the button down.
As mentioned by sudo rm -rf, UIAlertView has a limit.
You can try creating your own "alert" that doesn't clip by creating a view controller and showing it using presentModalViewController:animated:.

IOS4 UIButton Selected State Question (Error: Lvalue required as left operand of assignment)

In simple terms I have a view with three buttons;
buttonOne
buttonTwo
checkButtonStatus
if buttonOne is clicked it sets its own selected status to yes and buttonTwo selected status to no.
Clicking buttonTwo does the opposite.
Both buttonOne and buttonTwo by default are not selected.
The third button (checkButtonStatus) should perform a check to make sure at least one of the other two has been clicked.
I have the code detailed below:
- (IBAction)setButtonOne:(id)sender {
buttonOne.selected = YES;
buttonTwo.selected = NO;
}
- (IBAction)setButtonTwo:(id)sender {
buttonOne.selected = NO;
buttonTwo.selected = YES;
}
- (IBAction)checkButtons:(id)sender {
if (buttonOne.selected = NO || buttonTwo.selected = NO) {
UIAlertView *callAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"You have not selected a button"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[callAlert show];
[callAlert release];
}
}
The error I'm getting is 'Lvalue required as left operand of assignment'.
I'm not a programmer, I'm a sysadmin who's been asked to prototype something and can't get it working. All help greatly appreciated.
You need to use '==', not a single '=' when testing equality is your -checkButtons method.

UIActionSheet addButtonWithTitle: doesn't add buttons in the right order

I've subclassed UIActionSheet, and in the -init method, I have to add the buttons individually after calling the super init (can't pass a var_args).
Right now, it looks like this:
if (self = [super initWithTitle:title delegate:self cancelButtonTitle:cancel destructiveButtonTile:destroy otherButtonTitles:firstButton,nil]) {
if (firstButton) {
id buttonTitle;
va_list argList;
va_start(argList, firstButtton);
while (buttonTitle = va_arg(argList, id)) {
[self addButtonWithTitle:buttonTitle]
}
va_end(argList);
}
}
return self;
However, my specific use in this case has no destructive button, a cancel button, and four other buttons. When it shows up, the ordering is all off, showing up as
Button1
Cancel
Button2
Button3
Like they were simply added to the end of the list, which makes sense; however, I don't WANT it to look like this; so what do I do? Is there, in fact, any way to subclass UIActionSheet correctly and make this work?
You can just add them in your correct order, and then set the cancelButtonIndex and destructiveButtonIndex manually.
For your code example:
if (self = [super initWithTitle:title delegate:self cancelButtonTitle:nil destructiveButtonTile:nil otherButtonTitles:nil]) {
if (firstButton) {
id buttonTitle;
int idx = 0;
va_list argList;
va_start(argList, firstButtton);
while (buttonTitle = va_arg(argList, id)) {
[self addButtonWithTitle:buttonTitle]
idx++;
}
va_end(argList);
[self addButtonWithTitle:cancel];
[self addButtonWithTitle:destroy];
self.cancelButtonIndex = idx++;
self.destructiveButtonIndex = idx++;
}
}
return self;
Aviad Ben Dov's answer is correct, however the button index counter is not needed to set the index for the destroy and cancel indices. The addButtonWithTitle: method returns the index of the newly used button so we can use that value right away like so:
if (self = [super initWithTitle:title delegate:self cancelButtonTitle:nil destructiveButtonTile:nil otherButtonTitles:nil]) {
if (firstButton) {
id buttonTitle;
va_list argList;
va_start(argList, firstButtton);
while (buttonTitle = va_arg(argList, id)) {
[self addButtonWithTitle:buttonTitle]
}
va_end(argList);
self.cancelButtonIndex = [self addButtonWithTitle:cancel];
self.destructiveButtonIndex = [self addButtonWithTitle:destroy];
}
}
return self;
The earlier answers cause the destructive button to be placed at the bottom, which is not in accordance with the HIG, and which is also very confusing for the user. The destructive button should be at the top, the cancel on the bottom, and the others in the middle.
The following orders them correctly:
sheetView = [[UIActionSheet alloc] initWithTitle:title delegate:self
cancelButtonTitle:nil destructiveButtonTitle:destructiveTitle otherButtonTitles:firstOtherTitle, nil];
if (otherTitlesList) {
for (NSString *otherTitle; (otherTitle = va_arg(otherTitlesList, id));)
[sheetView addButtonWithTitle:otherTitle];
va_end(otherTitlesList);
}
if (cancelTitle)
sheetView.cancelButtonIndex = [sheetView addButtonWithTitle:cancelTitle];
See https://github.com/Lyndir/Pearl/blob/master/Pearl-UIKit/PearlSheet.m for an implementation (a UIActionSheet wrapper with a block-based API).