【问题标题】:UIActionSheet iOS 8 errorUIActionSheet iOS 8 错误
【发布时间】:2015-05-18 09:23:05
【问题描述】:

我正在尝试通过UITableViewCell 上的按钮在 iPad 上显示UIActionSheet。它在 iOS 7 上运行良好,但在 iOS 8 上无法正常运行。UIActionSheet 包含一些视觉伪影,我在控制台中收到此警告:

    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.

我的代码:

- (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];
    }
}

【问题讨论】:

    标签: ios cocoa-touch ios8 uiactionsheet nslayoutconstraint


    【解决方案1】:

    UIActionSheet 已弃用,因此您可以使用 iOS 8.0 或更高版本中提供的UIAlertViewController

    - (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];
    }
    

    【讨论】:

    • 您建议根据iOS版本决定运行时使用UIActionSheet还是UIAlertController?
    • @user1561346 没错。
    • UIAlertController 在控制台中具有相同的外观错误和相同的警告。没想到,真的。 :/ 当然我已经添加了alertController.popoverPresentationController.sourceRectalertController.popoverPresentationController.sourceView
    • 我已经尝试了相同的代码,一切都按预期工作。检查您的故事板可能存在一些限制问题。
    【解决方案2】:

    看起来您最喜欢的按钮超级视图太小而无法嵌入操作表。尝试使用窗口显示操作表,只是不要忘记转换收藏按钮的坐标:

    - (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];
        }
    }
    

    【讨论】:

    • 我认为视图不必足够大以适应它。它只是用来找位置的。但我尝试将 frame 转换为 self.view 和 self.navigationController.view。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    相关资源
    最近更新 更多