UIPopoverPresentationController being cut on iPad iOS 10 - ios

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 -

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!!

PresentViewController is not working in objective c. App is crashing

When I am trying to present alert view controller my app is crashing.
-(void)setupAlertCtrl{
self.alertCtrl=[UIAlertController alertControllerWithTitle:#"Select Image"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
}
- (IBAction)selectImagePressed {
**[self presentViewController:self.alertCtrl
animated:YES
completion:nil];//this funcanility is breaking**
}
Exception :
libc++abi.dylib: terminating with uncaught exception of type NSException
libc++abi.dylib: terminating with uncaught exception of type NSException
This could also happen if you've wired up a button to an IBAction that doesn't exist anymore (or has been renamed)"
If you're running into this problem than go to your storyboard, RIGHT click on the yellow box icon (view controller) at the top of the phone outline and DELETE the outlet(s) with yellow flags.
What happens in instances like this is you probably named an action, then renamed it.
Hope this will help you.
This code will definitely help you.
I suspect you are using iPad(normal action sheet crashes in iPad)
-(void)setupAlertCtrl
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:#"Your message" preferredStyle:UIAlertControllerStyleActionSheet];
// Remove arrow from action sheet.
[alertController.popoverPresentationController setPermittedArrowDirections:0];
//For set action sheet to middle of view.
CGRect rect = self.view.frame;
rect.origin.x = self.view.frame.size.width / 20;
rect.origin.y = self.view.frame.size.height / 20;
alertController.popoverPresentationController.sourceView = self.view;
alertController.popoverPresentationController.sourceRect = rect;
[self presentViewController:alertController animated:YES completion:nil];
}
else
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:#"Your message" preferredStyle:UIAlertControllerStyleActionSheet];
[self presentViewController:alert animated:YES completion:nil];
}
}
you have to call the below function in view did load
-(void)setupAlertCtrl
Then you can open the alert on button click
You should have to write it like,
-(void)setupAlertCtrl
{
self.alertCtrl=[UIAlertController alertControllerWithTitle:#"Select Image"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[self presentViewController:self.alertCtrl animated:YES completion:nil];
}
-(IBAction)selectImagePressed
{
[self setupAlertCtrl];
}
Hope this will help you.
UIAlertController is a functionally identical, block-based replacement for both UIAlertView and UIActionSheet. Switching between an alert or action sheet is done by setting the preferred style when creating the controller.
UIAlertController *alertController = [UIAlertController
alertControllerWithTitle:alertTitle
message:alertMessage
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertController animated:YES completion:nil];
I hope this will help you...
Its not crashing,
Just call the SetupAlertCntrl in viewDidLoad method.
Its working fine
You need to check your alertController exist or not first, if not let created it first. One more thing, UIAlertControl only can present from UIViewController so, make sure self in selectImagePressed function is kind of UIViewController.
- (IBAction)selectImagePressed {
if(self.alertController == nil) {
[self setupAlertCtrl];
}
[self presentViewController:self.alertCtrl
animated:YES
completion:nil];//this funcanility is breaking**
}
Try below code:
-(void)setupAlertCtrl
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"Choose Profile Image " message:#" " preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* cameraAction = [UIAlertAction actionWithTitle:#"Take Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"Camera Action");
}];
[alertController addAction:cameraAction];
UIAlertAction* gallaryAction = [UIAlertAction actionWithTitle:#"Gallary" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(#"Gallary Action");
}];
[alertController addAction:gallaryAction];
UIAlertAction* Cancel = [UIAlertAction actionWithTitle:#"Cancel" style:UIAlertActionStyleCancel handler:nil];
[alertController addAction:Cancel];
[self presentViewController:alertController animated:YES completion:nil];
}
// Button Click action
- (IBAction)selectImagePressed:(id)sender
{
[self setupAlertCtrl];
}
hope this will help you.

Programmatically made UIButton is not deleting when action fired

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.

UIAlertController - iOS 8 - iPad - Not Centering Properly

I'm trying to display a UIAlertController with some action buttons. It works fine on the iPhone, because it pops from the bottom of the device. I have a problem with the ipad, the UIAlertController does not center properly. It shows a bit off to the right. I can subtract from the x coordinate by subtracting say 150f. Is there a way to just get it center?
UIAlertController * view= [UIAlertController
alertControllerWithTitle:#"My Title"
message:#"Select your Choice"
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* ok = [UIAlertAction
actionWithTitle:#"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
//Do some thing here
[view dismissViewControllerAnimated:YES completion:nil];
}];
UIAlertAction* cancel = [UIAlertAction
actionWithTitle:#"Cancel"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action)
{
[view dismissViewControllerAnimated:YES completion:nil];
}];
[view addAction:ok];
[view addAction:cancel];
view.popoverPresentationController.sourceView = self.view;
view.popoverPresentationController.sourceRect = CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 0.0, 0.0);
[self presentViewController: view animated:YES completion:nil];
If you have simple actions then better to use Alertstyle, it centers automatically or if you insist to use Actionsheet style, try setting popoverPresentationController.permittedArrowDirections = 0 this works nice with a fixed orientation but fails if you rotate in iPad.
// Alert
- (void) showAlert
{
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"TEst" message:#"test Message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:#"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}];
[alertController addAction:cancelAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
}

UIAlertController : How to show all separator lines when added much actions?

When UIAlertController cannot show all action on screen, it can scroll.
But, separators disappears.
What should I do to display all separators?
iOS : 8.4
Xcode : 6.4
Example:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"test" message:#"test" preferredStyle:UIAlertControllerStyleActionSheet];
for ( int i = 0; i < 50; i++ ) {
[alertController addAction:[UIAlertAction actionWithTitle:[NSString stringWithFormat:#"%d", i] style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}]];
}
[self presentViewController:alertController animated:YES completion:^{
}];

Resources