I am working on a conference based application. I want to show an incoming call window to the user, I am using UIActionSheet to show that notification. Now, the problem here is that the call may come at any time from the server, at that we may be in our application any view, how can I show the incoming call notification using UIActionSheet? What delegate I have to set?
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:msg_string
delegate:(id)??????????????????
cancelButtonTitle:#"ACCEPT"
destructiveButtonTitle:#"DECLINE"
otherButtonTitles: nil];
Any suggestion is greatly appreciated.
Thanks.
an object that is guaranteed to be alive; e.g. the application's delegate. also, in a typical iOS application structure, it has a reference to the top level of the view hierarchy. -Alan
you should set like below.
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:msg_string
delegate:self
cancelButtonTitle:#"ACCEPT"
destructiveButtonTitle:#"DECLINE"
otherButtonTitles: nil];
delegate is class where to UIActionSheetDelegate method is implemented.
like e.g
#implementation ViewController
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{ // you code }
#end
so clickedButtonAtIndex is actionSheet delegate method which is in viewController Class and you alertView also shown from ViewController Class then you have to set self. or if alertView shown from other class and delegate method body written in ViewController class then as delegate you need to set object of ViewController class.
Related
I have a class that has an extension of UIButton that shows a UIAlertview under certain circumstance.
#interface CellButton : UIButton {}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"You Lose!"
message:#"Play Again?"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:#"cancel", nil];
[alert show];
This works fine, but I need to present a view controller when user presses ok.But as you may know you cannot present a view controller with an extension of UIButton.
So I was wondering if I can put the code below in another viewcontroller and allow it to work with the UIAlert in Cellbutton class.
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) { // and they clicked OK.
GameController*myNewVC = [[GameController alloc] init];
[self presentModalViewController:myNewVC animated:NO];
}
}
You don't do it inside the UIButton.
The target of clicking the UIButton should be a UIViewController. After that, show an alert view FROM the view controller, and the view controller will be the delegate of the UIButton. From their everything will work fine.
This would work as long as you have set the alert view delegate to the view controller you want to handle the presentation.
I would suggest moving all of the functionality to the view controller though, i.e. present and handle the alert view from the same view controller, this can be triggered from an event from the button. I think this makes the code more readable and it doesn't really make sense for a button to know about alert views
You can declare a global variable (in appDelegate - and how to do it HERE) then ;
1 - set the variable 1 when user click button
2 - get the value from other viewcontroller's action
if the value is 1 then go ahead.
I have an educational app working fine with tab bars. One of the tabs is a test for the user. If a user taking the test selects another tab, I would like an action sheet to display to confirm they really want to exit the test since their test results will be lost.
I can't get the action sheet to display. I am getting syntax errors with the first three examples below. The 4th example will compile OK but the app aborts. I can't figure out what should go after the self. Or possibly one of the other examples would work if I had the syntax correct.
- (void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController {
NSLog(#"Tab Bar Controller reached");
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:#"This will end the test.
Are you sure you want to leave?"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Yes,
cancel the test."
otherButtonTitles:nil];
[actionSheet showInView:self.view];
[actionSheet showInView:elements1AppDelegate.window];
[actionSheet showFromTabBar:self.tabBarController.tabBar];
[actionSheet showFromTabBar:self];
Ultimately, once I get the action sheet to display, I will either proceed to the tab selected or stay in the test view depending on whether the user decides to exit or not. Any help/suggestions would be appreciated. Thanks.
The name of the method tabBarController:didSelectViewController: should indicate that it's too late to stop the selection. Its return type void indicates there is not much you can do about it. Instead focus on method names that have "will" or "should" in them, and return types like BOOLs such as tabBarController:shouldSelectViewController:. So here is some basic code that does what you want.
I don't know the actual classname of your test's view controller so I'll use QuizController as a classname. QuizController is a UIViewController subclass.
QuizController.m
#interface QuizController () <UITabBarControllerDelegate,UIActionSheetDelegate>{
BOOL _testInProgress;
}
#end
#implementation QuizController
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// When a tabs view controller is presented viewDidAppear: will be called so here we will set this view controller as the tabBarController delegate so we get the callback.
self.tabBarController.delegate = self;
}
-(void)startQuiz{
_testInProgress = YES;
// Begin testing code
}
-(void)stopQuiz{
// Score test record results
_testInProgress = NO;
}
-(void)cancelQuiz{
// Throw out results
_testInProgress = NO;
}
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
if (!_testInProgress) return YES;
// If trying to select this controller then who cares?
if (viewController == self) return YES; // Or NO. Just don't show the sheet.
UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:#"You are in the middle of a test. Are you sure you want to switch tabs?"
delegate:self
cancelButtonTitle:#"Continue Test"
destructiveButtonTitle:#"Abort Test"
otherButtonTitles:nil];
// Lets cheat and use the tag to store the index of the desired view controller.
action.tag = [self.tabBarController.viewControllers indexOfObject:viewController];
[action showFromTabBar:self.tabBarController.tabBar];
return NO;
}
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{
if (buttonIndex == actionSheet.destructiveButtonIndex){
[self cancelQuiz];
// The above cheat pays off.
[self.tabBarController setSelectedIndex:actionSheet.tag];
}
}
EDIT (In response to comment quoted)
I'm a little confused about your example. Currently, my "take test"
class is a UIViewController. Are you suggesting I replace that with
your QuizController above?
No. I am suggesting that you take this code and integrate the design pattern into your UIViewController subclass that handles your test. Although this is a working example (providing you supply UI to toggle the _testInProgress ivar.)
Do I leave my current UITabBarController in place?
Yup.
That is currently my appdelegate and rootController.
Huh? Your UITabBarController is almost certainly your rootViewController. But unless you have done something very odd like AppDelegate : UITabBarController <UIApplicationDelegate>, by the way don't do that, then it is extremely unlikely that your "appdelegate" and your UITabBarController are the same. Much more likely your AppDelegate is your tabBarController's delegate.
If just setting the tabBarController.delegate property on appearance is bad (and it could very well be), i.e. some other object needs to be the tabBarController's delegate, then you'll have to forward a message to that view controller to see if a test is in progress. For this you could actually leave almost all of the code in the example unchanged. Of course you would have to remove the self.tabBarController.delegate = self; in viewDidAppear:. And put the following in your AppDelegate(presuming that's the tabBarController's delegate):
-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
if ([tabBarController.selectedViewController respondsToSelector:#selector(tabBarController:shouldSelectViewController:)]){
return [(NSObject <UITabBarControllerDelegate>*)tabBarController.selectedViewController tabBarController:tabBarController shouldSelectViewController:viewController];
}
return YES;
}
This implementation essentially forwards the responsibility to answer the question to the view controller, provided it will answer the question.
I check in there if the "take test" tab was selected and call an
initialization method in my "take test" class.
In my opinion the "take test" view controller should simply become selected when the user taps the tab for it. And its view should contain a button with something to the effect of 'start test' on it. But that's just my opinion.
But whatever the case is the application's knowledge of whether the user is taking a test should reside in the view controller that administers the test.
[actionSheet showInView:[[[UIApplication sharedApplication] windows] objectAtIndex:0]];
Did you try this One Link
I create custom login page by using UIAlerView subclass. Now when i click on button it opens up UIAlertView I want to change the main view based on which button is pressed.
But as all implementation of UIAlerView is in another class though i change the view it doesn't retain that as that class variable doesn't get it's value.
Can anyone please help me with this? I can post the code if required.
Thank you,
Ankita
You can use a custom init method like below for alertView and store the _sender in global or class variable. like
id sender;
- (id)initWithSender:(id)_sender
{
self = [super init];
if (self) {
sender=_sender;
}
return self;
}
from RootVC/bgview initialize alertView as follows and define a method named
-(void) alertIndexSelected:(NSInterger) index;
{
//change the backgound view based on button selected
}
in rootvc/your main view.
alertViewobj =[[alertView alloc] initWithSender:self];
when the button is selected on alertview call the below method, this will notify your rootvc about which index of alert is pressed. use following alertview delegate.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[sender alertIndexSelected: buttonIndex];
}
If you are planning to use delegate methods then I think you need to referrer to some of these links.
How to use custom delegates in Objective-C
How do I create delegates in Objective-C?
http://iosdevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html
I hope this will help you a great deal in understanding delegates.
In my iPhone app, I have an actionsheet which has 4 buttons.
Now to perform actions on click of these buttons, I have implemented ActionSheet Delegate.
The action sheet delegate method does not get called on click of the buttons. The same code works when integrated to another project.
I have declared all the method names properly.
Below is the screenshot which shows the delegate method
What could be wrong?
Make sure you have set your UIActionSheet delegate to self:
actionSheet.delegate = self;
and also make sure you're implementing <UIActionSheetDelegate> in the header file.
If you use the code to call the action sheet like below
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"YOUR TITLE" delegate:self cancelButtonTitle:nil destructiveButtonTitle:#"YOUR MESSAGE" otherButtonTitles:#"Cancel", nil];
[actionSheet showInView:self.view];
[actionSheet release];
Then there won't be an issue calling the delegate method,
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
Cheers
I learned how to create a view controller and make the view slide in from bottom. But the one in iphone album looks different. It darkens the rest of the visible portion of the screen when the view slides in. How do I create a similar one? I want to add buttons like "save, cancel, email" etc into the sliding view.
This actually isn't a typical "sliding" (or modal) view, but a UIActionSheet. Basically, the idea is that you initialize the view (usually in your view controller) with
UIActionSheet *sheet =
[[[UIActionSheet alloc] initWithTitle:#"My sheet"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Email", #"MMS", nil] autorelease];
Then present it using
[sheet showInView:[self view]];
Once it's onscreen, the delegate (self, or your view controller, in this example) will receive the UIActionSheetDelegate message actionSheet:clickedButtonAtIndex: (as well as some others; see the documentation for more), so you'll want to add <UIActionSheetDelegate> to your interface declaration for the delegate and implement that method, like
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
switch(buttonIndex) {
// Do things based on which button was pushed
}
}