Programmatically made UIButton is not deleting when action fired - ios

Currently I have a button that makes a draggable UIView with a subview of a UIButton. When I long press that UIButton, an alert view comes up and I have two buttons, a delete button and a cancel button. The delete button is supposed to delete the last long pressed UIButton, however it deletes the most recently made UIButton.
I would like for the delete button on the alert view to delete the last long pressed UIButton.(not the most recently created) I have tried different if statements, but this is what I have so far. Here is my code for my .m file:
- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateBegan ) {
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Would you like to delete this rep?"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* deleteButton = [UIAlertAction
actionWithTitle:#"Delete"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[_buttonField removeFromSuperview];
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancelButton = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:deleteButton];
[alert addAction:cancelButton];
[self presentViewController:alert animated:YES completion:nil];
}
}
- (void)panWasRecognized:(UIPanGestureRecognizer *)panner {
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPress:)];
[self.buttonField addGestureRecognizer:longPress];
_draggedView = panner.view;
CGPoint offset = [panner translationInView:_draggedView.superview];
CGPoint center = _draggedView.center;
_draggedView.center = CGPointMake(center.x + offset.x, center.y + offset.y);
_draggedView.layer.borderWidth = 2.0f;
_buttonField.layer.borderColor = [UIColor blackColor].CGColor;
[_buttonField setTintColor:[UIColor magentaColor]];
// Reset translation to zero so on the next `panWasRecognized:` message, the
// translation will just be the additional movement of the touch since now.
[panner setTranslation:CGPointZero inView:_draggedView.superview];
}
}
- (IBAction)addRepButton:(UIBarButtonItem *)newRep {
self.labelCounter++;
buttonCount ++;
if (buttonCount >= 0 )
{
_buttonField = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 28, 28)];
[_buttonField setTitle:[NSString stringWithFormat:#"%i", self.labelCounter]forState:UIControlStateNormal];
[_buttonField setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_buttonField.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
_buttonField.userInteractionEnabled = YES;
_buttonField.layer.cornerRadius = 14;
_buttonField.layer.borderColor = [UIColor blackColor].CGColor;
_buttonField.layer.borderWidth = 2.0f;
_buttonField.titleLabel.font = [UIFont systemFontOfSize: 18];
UIPanGestureRecognizer *panner = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(panWasRecognized:)];
[_buttonField addGestureRecognizer:panner];
[self.view addSubview:_buttonField];
}
}
How do I go about making the delete button remove the most recently long pressed _buttonField?

You are saying:
[_buttonField removeFromSuperview];
Well, as your loop shows (inside addRepButton), _buttonField is the most recently added button, because every time you add a button, you set it to that button. So what is happening is exactly what you are saying to happen.
I presume, although it is a little hard to tell from your code, that the button you want to delete is the one whose long press gesture recognizer this is — that is, gesture.view.

- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateBegan ) {
//Update
UIButton *buttonPressedLatest;
UIView *ifBtnPressed = gesture.view;
if([ifBtnPressed isKindOfClass:[UIButton class]]){
buttonPressedLatest = (UIButton *)ifBtnPressed;
}
UIAlertController * alert= [UIAlertController
alertControllerWithTitle:#"Would you like to delete this rep?"
message:nil
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* deleteButton = [UIAlertAction
actionWithTitle:#"Delete"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[buttonPressedLatest removeFromSuperview];
[alert dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancelButton = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:deleteButton];
[alert addAction:cancelButton];
[self presentViewController:alert animated:YES completion:nil];
}
}
Try this once and tell me if this works.

Related

Change the UIAlertController buttons background color

Is it possible to change the background color of UIAlertController? I have managed to change the background color of UIAlertView. I have gone through third parties also to do the same, but I want o do it without use of any third party.
Below is my code:
UIAlertController * alert=[UIAlertController alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIView *firstSubview = alert.view.subviews.firstObject;
UIView *alertContentView = firstSubview.subviews.firstObject;
for (UIView *subSubView in alertContentView.subviews) {
subSubView.backgroundColor = [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f];
}
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
//Close Action
}];
UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:#"Delete" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){
//Close Action
}];
[cancelAction setValue:[UIColor greenColor] forKey:#"titleTextColor"];
[deleteAction setValue:[UIColor redColor] forKey:#"titleTextColor"];
[alert addAction:cancelAction];
[alert addAction:deleteAction];
[self presentViewController:alert animated:YES completion:nil];
Thanks in advance!!

display the data on the tag of UIButton in objective-c

I have stored 5 images in an NSMutableArray named as _dict in the code.
In .h file:
#property(weak,nonatomic)IBOutlet UIButton *b1;
#property(weak,nonatomic)IBOutlet UIButton *b2;
#property(weak,nonatomic)IBOutlet UIButton *b3;
#property(weak,nonatomic)IBOutlet UIButton *b4;
#property(weak,nonatomic)IBOutlet UIButton *b5;
#property(weak,nonatomic)IBOutlet UIButton *b6;
#property(weak,nonatomic)IBOutlet UIButton *b7;
#property(weak,nonatomic)IBOutlet UIButton *b8;
#property(weak,nonatomic)IBOutlet UIButton *b9;
In.m file
dict=[[NSMutableArray alloc]init];
dict= _array;
NSLog(#"%#",dict);
colorimage = [dict objectAtIndex:0];
[_b1 setBackgroundImage:colorimage forState:UIControlStateNormal];
colorimage1 = [dict objectAtIndex:1];
[_b2 setBackgroundImage:colorimage1 forState:UIControlStateNormal];
colorimage2 = [dict objectAtIndex:2];
[_b3 setBackgroundImage:colorimage2 forState:UIControlStateNormal];
colorimage3 = [dict objectAtIndex:3];
[_b4 setBackgroundImage:colorimage3 forState:UIControlStateNormal];
colorimage4 = [dict objectAtIndex:4];
[_b5 setBackgroundImage:colorimage4 forState:UIControlStateNormal];
int j=0;
img=[[NSMutableArray alloc]init];
}
-(IBAction)button1:(id)sender{
k++;
[img addObject:colorimage];
[sender setBackgroundImage:[UIImage imageNamed:#"apple.png"] forState:UIControlStateNormal];
[self check];
}
-(IBAction)button2:(id)sender{
k++;
[img addObject:colorimage1];
[sender setBackgroundImage:[UIImage imageNamed:#"apple.png"] forState:UIControlStateNormal];
[self check];
}
-(IBAction)button3:(id)sender
{
k++;
[img addObject:colorimage2];
[sender setBackgroundImage:[UIImage imageNamed:#"apple.png"] forState:UIControlStateNormal];
[self check];}
-(IBAction)button4:(id)sender
{
k++;
[img addObject:colorimage3];
[sender setBackgroundImage:[UIImage imageNamed:#"apple.png"] forState:UIControlStateNormal];
[self check];
}
-(IBAction)button5:(id)sender
{
k++;
[img addObject:colorimage4];
[sender setBackgroundImage:[UIImage imageNamed:#"apple.png"] forState:UIControlStateNormal];
[self check];
}
-(IBAction)button6:(id)sender
{
}
-(IBAction)button7:(id)sender
{
}
-(IBAction)button8:(id)sender
{
}
-(IBAction)button9:(id)sender
{
}
-(void)check{
if(k==5)
{
// NSArray *arr1 = [[NSArray alloc]initWithObjects:#"aa",#"bb",#"1",#"cc", nil];
// NSArray *arr2 = [[NSArray alloc]initWithObjects:#"aa",#"bb",#"1",#"cc", nil];
if([dict isEqualToArray:img])
{
NSLog(#"equal");
UIAlertController * alert=[UIAlertController alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* Retry = [UIAlertAction actionWithTitle:#"you got"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
NSLog(#"you pressed Yes, please button");
// call method whatever u need
}];
[alert addAction:Retry];
[self presentViewController:alert animated:YES completion:nil];
}
else{
NSLog(#"not equal........");
UIAlertController * alert=[UIAlertController alertControllerWithTitle:#"Title"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* Retry = [UIAlertAction actionWithTitle:#"please try again............"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
NSLog(#"you pressed Yes, please button");
// call method whatever u need
}];
[alert addAction:Retry];
[self presentViewController:alert animated:YES completion:nil];
}
}
// else
// {
// UIAlertController * alert=[UIAlertController alertControllerWithTitle:#"Title"
// message:#"Message"
// preferredStyle:UIAlertControllerStyleAlert];
// UIAlertAction* Retry = [UIAlertAction actionWithTitle:#"please try again"
// style:UIAlertActionStyleDefault
// handler:^(UIAlertAction * action)
// {
// NSLog(#"you pressed Yes, please button");
// call method whatever u need
// }];
// [alert addAction:Retry];
// [self presentViewController:alert animated:YES completion:nil];
// }
}
i got the images.But as i told ,i have stored 5 images in dict.i need to display the images randomly tag of UIbutton.I tried with many code.But not got.
And also i have stored 10 images in NSMutableArray .And i need to select randomly 4 images from the array and need to display the image where unfilled uibutton img(that is...already 5 images will display on different tag of UIButtons and remaining 4 UIButton should display the images which is stored in array of 10 images).how to do?
The good way to use is to go for IBOutletCollection.
Instead of creating so many outlets you can use IBOutletCollection and make your code small. When you do that you can collect all your 9 buttons inside one array.
#IBOutlet var buttons: [UIButton]!
Now let's assume you have random tags generated - use some random generator - and stored inside:
var randomTags: [Int]
Now you can use this beautiful Swift syntax to filter and get new buttons array which has only those buttons whose tag is randomly generated and stored inside randomTags
let newButtons = buttons.filter { (button) -> Bool in
return randomTags.contains(button.tag)
}
Hope it helps.

UIPopoverPresentationController being cut on iPad iOS 10

Im trying to show a list inside a popover controller using
UIAlertController. Works well on iOS 8, 9. On iOS 10 ipad it gets cut. Although I am adding actions and verified it is being added but the popover gets cut. Please suggest . Below is my code -
UIAlertController * view= [UIAlertController
alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
if(IS_IPAD) {
UIPopoverPresentationController *popPresenter = [view
popoverPresentationController];
[view setModalPresentationStyle:UIModalPresentationPopover];
[view setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
popPresenter.sourceView = self.view;
popPresenter.sourceRect = CGRectMake(70, 0, self.view.frame.size.width, self.view.frame.size.height);
popPresenter.barButtonItem = self.navigationItem.leftBarButtonItem;
}
// Add Cacel Action
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"إلغاء", #"'Cancel' title for button")
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * action) {
[view dismissViewControllerAnimated:YES completion:nil];
}];
[view addAction:cancelAction];
[self.liveFeed.filter.filtersItems enumerateObjectsUsingBlock:^(DPFilteritem *item, NSUInteger idx, BOOL * _Nonnull stop) {
if (![item.filterName isKindOfClass:[NSNull class]] && item.filterName.length > 0) {
UIAlertAction* alertAction = [UIAlertAction
actionWithTitle:item.filterName
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here
NSUInteger index = [[view actions]indexOfObject:action];
[view dismissViewControllerAnimated:YES completion:nil];
[self didSelectAlertItemAtIndex:index];
}];
[view addAction:alertAction];
}
}];
view.view.tintColor = [UIColor blackColor];
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:view animated:YES completion:^{
//fix for iOS 9 - known issue in iOS9. You need to set tint color in completion handler.
view.view.tintColor = [UIColor blackColor];
}];
});
iOS 10 - ipad -
iOS 9 - ipad -

UIActionSheet iOS 8 error

I'm trying to show UIActionSheet on iPad from button on UITableViewCell. It works fine on iOS 7, but not working properly on iOS 8. UIActionSheet containts some visual artifacts and I'm getting this warning in console:
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x79793de0 H:[UIView:0x797a7630(304)]>",
"<NSLayoutConstraint:0x7a16ae00 UIView:0x7a16ab60.width == _UIAlertControllerView:0x797a9230.width>",
"<NSAutoresizingMaskLayoutConstraint:0x7a66f2a0 h=--& v=--& H:[UIView:0x7a16ab60(298)]>",
"<NSLayoutConstraint:0x797a49e0 _UIAlertControllerView:0x797a9230.width >= UIView:0x797a7630.width>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x79793de0 H:[UIView:0x797a7630(304)]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
My code:
- (void)onFavoriteBtn:(id)sender {
CGPoint btnPosition = [sender convertPoint:CGPointZero toView:_tableView];
NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:btnPosition];
if (indexPath) {
UIButton *favoriteBtn = (UIButton *)sender;
CGRect favoriteBtnRect = favoriteBtn.frame;
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Remove from Favorites" otherButtonTitles:nil];
[sheet showFromRect:favoriteBtnRect inView:favoriteBtn.superview animated:true];
}
}
UIActionSheet is deprecated, so you can use UIAlertViewController available in iOS 8.0 or later.
- (IBAction)onFavoriteBtn:(id)sender {
CGPoint btnPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:btnPosition];
if (indexPath) {
[self showActionSheet:sender];
}
}
- (void)showActionSheet:(UIView *)sender
{
NSString *alertTitle = NSLocalizedString(#"ActionTitle", #"Archive or Delete Data");
NSString *alertMessage = NSLocalizedString(#"ActionMessage", #"Deleted data cannot be undone");
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:alertTitle
message:alertMessage
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"Cancel", #"Cancel action")
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
NSLog(#"Cancel action");
}];
UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"Delete", #"Delete action")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action)
{
NSLog(#"Delete action");
}];
UIAlertAction *archiveAction = [UIAlertAction actionWithTitle:NSLocalizedString(#"Archive", #"Archive action")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(#"Archive action");
}];
[alertController addAction:cancelAction];
[alertController addAction:deleteAction];
[alertController addAction:archiveAction];
UIPopoverPresentationController *popover = alertController.popoverPresentationController;
if (popover)
{
popover.sourceView = sender;
popover.sourceRect = sender.bounds;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
[self presentViewController:alertController animated:YES completion:nil];
}
Looks like your favorite button superview is too small to embed action sheet. Try to use window to display action sheet, just don't forget convert coordinates of favorites button:
- (void)onFavoriteBtn:(id)sender {
CGPoint btnPosition = [sender convertPoint:CGPointZero toView:_tableView];
NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:btnPosition];
if (indexPath) {
UIButton *favoriteBtn = (UIButton *)sender;
CGRect frame = [self.window convertRect:favoriteBtn.bounds fromView:favoriteBtn];
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Remove from Favorites" otherButtonTitles:nil];
[sheet showFromRect:frame inView:self.window animated:true];
}
}

Dismiss UIAlertControllerStyleAlert UIAlertController by tapping outside

As everyone's aware, UIAlertView is deprecated now and Apple wants us to use the new UIAlertController with the style UIAlertControllerStyleAlert. However, using the UIAlertControllerStyleAlert you cannot trigger the UIAlertAction with style UIAlertActionStyleCancel by tapping outside the alert view.
Does anyone know of a way to dismiss the alert view by tapping outside of it?
Cheers
You can add a separate cancel action with style UIAlertActionStyleCancel for the alertViewController so that when user taps outside, you would get the callback.
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Alert Title" message:#"A Message" preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
// Called when user taps outside
}]];
Try this code:
- (void)viewDidLoad {
[super viewDidLoad];
[self button];
}
- (void) button {
UIButton * AlertButton = [UIButton buttonWithType:UIButtonTypeSystem];
[AlertButton setTitle:#"Button" forState:UIControlStateNormal];
AlertButton.frame = CGRectMake((self.view.frame.size.width/2) - 50 , (self.view.frame.size.height/2) - 25, 100, 50);
[AlertButton addTarget:self action:#selector(Alert) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:AlertButton];
}
- (void)Alert {
UIAlertController * alert = [UIAlertController alertControllerWithTitle:#"Alert Title" message:#"Alert Message" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController: alert animated: YES completion:^{ alert.view.superview.userInteractionEnabled = YES; [alert.view.superview addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget: self action: #selector(DismissAlertByTab)]]; }];
}
- (void)DismissAlertByTab
{
[self dismissViewControllerAnimated: YES completion: nil];
}

Resources