Converting Swift block to Objective-C block - objective-c

In Swift, I have created a closure method (I think):
func firstMove(action: UIAlertAction!) {
if action.title == "Yes" {
currentPlayer = "X"
} else {
currentPlayer = "0"
}
That I pass into this UIAlertAction method:
let optionToStartController = UIAlertController(title: "", message: "Do you want first move?", preferredStyle: .Alert)
optionToStartController.addAction(UIAlertAction(title: "Yes", style: .Default, handler: firstMove))
How can I convert both the closure and method to Objective-C?
I have tried doing:
- (void)firstMove:(UIAlertAction*)action
{
if ([action.title isEqual: #"Yes"]) {
_currentPlayer = 'X';
} else {
_currentPlayer = 'O';
}
}
And passing it like this:
UIAlertController *optionToStartController = [UIAlertController alertControllerWithTitle:#"" message:#"Do you want first move?" preferredStyle:UIAlertControllerStyleAlert];
[optionToStartController addAction:[UIAlertAction actionWithTitle:#"Yes" style:UIAlertActionStyleDefault handler: firstMove]];

You may be looking for blocks, the objective-C rough equivalent of closures. I'm not quite sure what you're trying to accomplish, but the following code defines block firstMove and how it is passed and called from method addAction.
void(^firstMove)(int) = ^(int x){
NSLog(#"print y: %d", x);
};
[self addAction:firstMove];
...
-(void)addAction:(void(^)(int))y{
y(5);
}

You can see the example. It should work properly.
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Question"
message:#"Do you want first move?"
preferredStyle:UIAlertControllerStyleAlert];
//First button
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"YES"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Actions if the user press this button
//Dismiss the alertController. It's preferred to be in all actions.
[alert dismissViewControllerAnimated:YES completion:nil];
_currentPlayer = #"X";
}];
//Second Button
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"NO"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Actions if the user press this button
//Dismiss the alertController. It's preferred to be in all actions.
[alert dismissViewControllerAnimated:YES completion:nil];
_currentPlayer = #"O";
}];
//Add the actions to the alertController
[alert addAction:ok];
[alert addAction:cancel];
//present the alertController on the device. If you are writing this in the viewController, you can use self.view, if you are in UIView, then just self
[self.view presentViewController:alert animated:YES completion:nil];

Related

Using dismissViewController with UIAlertController

I'm updating an Objective-C application in iOS and since UIAlertView is deprecated I'm using UIAlertController with UIAlertAction for the OK and Cancel buttons. So I have the following function for the back button but I don't know how to handle the OK and Cancel buttons since the OK should let you go back to the previous screen and the Cancel should let you stay in the same screen. The following is my code so far.
- (void)backAction:(id)sender
{
//do your saving and such here
if ([doneBtn isEnabled])
{
//CHANGE 2018
UIAlertController *alert = [UIAlertController alertControllerWithTitle: #"Alert" message:#"Signature will be lost. Do you want to continue?." preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle: #"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
//should go to the previous scree.
//[alert dismissViewControllerAnimated:TRUE completion:nil]; //I'm not sure if this only hides the alert or hides the entire screen
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle: #"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
//should stay in the same screen
[alert dismissViewControllerAnimated:TRUE completion:nil]; //the same doubt
}];
[alert addAction: ok];
[alert addAction: cancel];
[self presentViewController:alert animated:YES completion:nil];
//UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Alert" message:#"Signature will be lost. Do you want to continue?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok",nil];
//[alert show];
}
The statement [alert dismissViewControllerAnimated:TRUE completion:nil] will only dismiss the alert, because it's the top view controller on the screen.
So, you don't need to do anything else for your Cancel action.
For your Ok action, you have multiple actions to go back to the previous screen :
If your view controller is a UIViewController alone, simply call [self dismissViewControllerAnimated:TRUE completion:nil]`
If the view controller is embedded into a navigation controller, call [self.navigationController popToRootViewControllerAnimated:YES].
You also can use an unwind segue to the view controller you want to go back too.
I hope it will help you! ;)
It is not necessary to call [alert dismissViewControllerAnimated:TRUE completion:nil];, when you tap on one of the button the alert is dismissed.
In the completion of your ok button if your viewController is in embedded in a navigationController you can use [self.navigationController popToRootViewControllerAnimated:YES];.
The above answers are correct. I actually wanted to comment but I don't have enough reputation.
You should try to take a look at this thread to get a better understanding of dismissing a viewController.
Dismissing a Presented View Controller
Try this, hope this will solve your issue.
UIAlertController * alert=[UIAlertController alertControllerWithTitle:#"Title"
message:#"Message"preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okButton = [UIAlertAction
actionWithTitle:#"Ok, please"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[self okButtonPressed];
}];
UIAlertAction* cancelButton = [UIAlertAction
actionWithTitle:#"No, thanks"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[self cancelButtonPressed];
}];
[alert addAction:okButton];
[alert addAction:cancelButton];
[self presentViewController:alert animated:YES completion:nil];
Now Dismiss the viewcontroller.
- (void)cancelButtonPressed{
// Write your implementation for Cancel button here.
}
- (void)okButtonPressed{
//Write your implementation for Ok button here
}

Application tried to present modally an active controller, why this code is crashing, knows anything about it?

UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:#"Select Language"
message:#""
preferredStyle:UIAlertControllerStyleActionSheet];
//We add buttons to the alert controller by creating UIAlertActions:
for (int j =0 ; j<val.count; j++)
{
NSString *titleString = val[j];
UIAlertAction * action = [UIAlertAction actionWithTitle:titleString style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
}];
[alertController addAction:action];
[self presentViewController:alertController animated:YES completion:nil];
You should only present the alert controller once. Move it out of your loop, and it should work.

How to give toast message in objective c

I am trying to give a toast message when users login and user will able to see a toast message saying New Data Available and the button beneath that says Download and Cancel.But when Download comes its font Coming in BOLD.PLease let me know how can i make this look in normal by default fonts
Code as follows:
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:msg message:#""delegate:self cancelButtonTitle:#"Download" otherButtonTitles: #"Ignore",nil];
I need the Download should Come in normal fonts in toast message.
I have a Simple code to giving Toast.
- (void) ShowAlert:(NSString *)Message {
UIAlertController * alert=[UIAlertController alertControllerWithTitle:nil
message:#""
preferredStyle:UIAlertControllerStyleAlert];
UIView *firstSubview = alert.view.subviews.firstObject;
UIView *alertContentView = firstSubview.subviews.firstObject;
for (UIView *subSubView in alertContentView.subviews) {
subSubView.backgroundColor = [UIColor colorWithRed:141/255.0f green:0/255.0f blue:254/255.0f alpha:1.0f];
}
NSMutableAttributedString *AS = [[NSMutableAttributedString alloc] initWithString:Message];
[AS addAttribute: NSForegroundColorAttributeName value: [UIColor whiteColor] range: NSMakeRange(0,AS.length)];
[alert setValue:AS forKey:#"attributedTitle"];
[self presentViewController:alert animated:YES completion:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[alert dismissViewControllerAnimated:YES completion:^{
}];
});
}
Use
[self ShowAlert:#"Please Enter Your Good Name."];
check it
UIAlertController* alert = [UIAlertController
alertControllerWithTitle:#"your text"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[self performSelector:#selector(abc:) withObject:alert afterDelay:2];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"Download"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
}];
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
}];
[alert addAction:ok];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil]
;
delegate method for automatic disappear
-(void)abc:(UIAlertController*)x{
[x dismissViewControllerAnimated:YES completion:nil];
}
As per your requirement you need to create one custom Alert View which match your expectations.
For you reference you can choose custom alerts which allow features which you want. (see example links below)
1) Example_1: https://github.com/cs-joao-souza/JPAlertController
2) Example_2: https://github.com/kubacizek/ScrollableDisclaimerAlert
3) Example_3: https://github.com/gokulgovind/GLInAppPurchase
Hope it helps.

How to display UIActionSheet on the Bottom of ipad same as iphone in objective c

I am new to iOS and I am facing a problem regarding UIActionSheet.
My code is like this
-(IBAction)picimgbtnClick:(id)sender
{
UIActionSheet *popup = [[UIActionSheet alloc] initWithTitle:#"Profile Photo" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:
#"Gallery",
#"Camera",
#"Remove Photo",
nil];
popup.tag = 1;
[popup showInView:self.view];
}
This works perfectly on iPhone but when I run this on an iPad, the UIActionSheet appears in the middle (see image below) and also doesn't show a cancel button:
On iPhone, it appears like this:
At first UIActionSheet is now deprecated so use latest code for it.
- (IBAction)capture:(UIButton *)sender {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:#"Title" message:#"Message" preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:#"Camera" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// Code for Cam
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Gallery" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//Code for Gallery
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Remove Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//Code for removing photo
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
[alert setModalPresentationStyle:UIModalPresentationPopover];
UIPopoverPresentationController *popPresenter = [alert popoverPresentationController];
popPresenter.sourceView = sender;
popPresenter.sourceRect = sender.bounds; // You can set position of popover
[self presentViewController:alert animated:TRUE completion:nil];
}
And as #balkaran singh said it's a default behaviour for ipad . you can not change it. If you want then you concrete your custom class and by animation you can get exact UI what you need.
Here methods showInView and showFromRect makes differences where on iPhone you will get the cancel option using showInView method but the same function you use in iPad you will not get.
Here are some methods you can customize your actionSheet origin see below image:
UIActionSheet's showFromRect:inView:animated: method is only supposed to be used on iPad. Its behavior on iPhone is undefined.
Hope this helps you.
You cannot show an action sheet from the bottom on the iPad, what you can do is show an alert.
The UIActionSheet class in deprecated since iOS 8, and should no longer be used. Instead you should make use of the UIAlertController. This works almost the same way:
UIAlertController *alert =
[UIAlertController alertControllerWithTitle:#"Profile Photo"
message:#"Select method of input"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:#"Gallery"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
NSLog(#"Clicked Gallery");
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Camera"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
NSLog(#"Clicked Camera");
}]];
[alert addAction:[UIAlertAction actionWithTitle:#"Remove Photo"
style:UIAlertActionStyleDefault
handler:^void (UIAlertAction *action) {
NSLog(#"Clicked Remove Photo");
}]];
[self presentViewController:alert animated:YES completion:nil];
This will present the options as an alert, which is analogous to the alert sheet on the iPhone:
There is no supported way of showing it the exact same way (from the bottom) as on the iPhone. If you think about it, it is very hard to reach the bottom of the iPad from many ways of holding it. The center makes much more sense.

how to pass parameter on completion block in objective-c

I am trying to declare a function with couple of blocks inside it, when I will call the function from viewdidload method, these parameters should perform accordongly
-(void) alertViewOn:(UILabel*)LabelTextX :(UIButton*)ButtonA :(UIButton*)ButtonB :(UIImage*)ImageX {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Enter Pet Name" message:nil preferredStyle:UIAlertControllerStyleAlert];
//Show TextField
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.placeholder = NSLocalizedString(#"Pet Name", #"Name");
}];
//Set Ok Button
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
[alert dismissViewControllerAnimated:YES completion:nil];
UITextField *textField = alert.textFields.firstObject;
self.labelText2.text = textField.text;
}];
[alert addAction:ok];
//Set ADD Button
UIAlertAction* addPet = [UIAlertAction actionWithTitle:#"Add More" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
[alert dismissViewControllerAnimated:YES completion:nil];
self.button4.hidden = NO;
self.button5.hidden = NO;
self.image2.hidden = NO;
}];
[alert addAction:addPet];
//Set Cancel Button
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
}
Here I want to pass the parameter LabelTextX to labelText2 ; ButtonA to button4 ; ButtonY to button5 and ImageX to image2 . I am totally new in objective-c and finding it difficult even to declare a function !!! Please any kind person help ....
-(void) alertViewOn:(UILabel*)LabelTextX :(UIButton*)ButtonA : (UIButton*)ButtonB :(UIImageView*)ImageX {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:#"Enter Pet Name" message:nil preferredStyle:UIAlertControllerStyleAlert];
//Show TextField
[alert addTextFieldWithConfigurationHandler:^(UITextField *textField)
{
textField.placeholder = NSLocalizedString(#"Pet Name", #"Name");
}];
//Set Ok Button
UIAlertAction* ok = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
[alert dismissViewControllerAnimated:YES completion:nil];
UITextField *textField = alert.textFields.firstObject;
LabelTextX.text = textField.text;
}];
[alert addAction:ok];
//Set ADD Button
UIAlertAction* addPet = [UIAlertAction actionWithTitle:#"Add More" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
[alert dismissViewControllerAnimated:YES completion:nil];
ButtonA.hidden = NO;
ButtonB.hidden = NO;
ImageX.hidden = NO;
}];
[alert addAction:addPet];
//Set Cancel Button
UIAlertAction* cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
}
And then called the function like this ...
- (IBAction)buttonPressed15:(id)sender {
[self alertViewOn:_labelText15 :_button30 :_button31 :_image15];
}