尝试对UIMenuController调用becomeFirstResponder时出错

时间:2014-11-14 11:21:01

标签: ios objective-c swift ios8 becomefirstresponder

我有一个信使,所以我想在细胞长按上显示UIMenuController。 enter image description here 我需要图像视图来抓住长按,因为我有文本和媒体消息。但是在iOS 8上收到长按手势后我收到了becomeFirstResponder电话崩溃(iOS 7效果很好):

*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UICompatibilityInputViewController: 0x13fd75b90> should have parent view controller:<FriendPlay.WLDialogViewController: 0x13fd54d10> but requested parent is:<UIInputWindowController: 0x140815000>'

这是代码的一部分:

override func handleLongPress(longPress: UILongPressGestureRecognizer!) {
    let alpha: CGFloat = 0.6
    let point = longPress.locationInView(tableView)
    let indexPath = tableView.indexPathForRowAtPoint(point)
    if indexPath != nil {
        let cell = tableView.cellForRowAtIndexPath(indexPath!) as MessageCell
        let convertedPoint = longPress.locationInView(cell.balloonImageView)
        if CGRectContainsPoint(cell.balloonImageView.frame, convertedPoint) {
            var myView = cell.balloonImageView
            if cell.message.type == MessageType.Text {
                cell.balloonImageView.alpha = alpha
            }
            else {
                myView = cell.mediaImageView
                cell.mediaImageView.alpha = alpha
            }
            if longPress.state == UIGestureRecognizerState.Began {
                showMenuAtPoint(convertedPoint, myView: myView)
            }
        }
    }
}

private func showMenuAtPoint(point: CGPoint, myView: MessageImageView) {
    myView.becomeFirstResponder()// <--- that crashes

    let rect = CGRectMake(point.x, point.y, 0, 0)
    let mc = UIMenuController.sharedMenuController()
    mc.setTargetRect(rect, inView: myView)
    let sendItem = UIMenuItem(title: "Send", action: "sendAgain:")
    mc.menuItems = [sendItem]
    mc.setMenuVisible(true, animated: true)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "menuDidHide:", name: UIMenuControllerDidHideMenuNotification, object: nil)
}

func sendAgain(sender: AnyObject) {
    println("Send!")
}

对于类MessageImageView(继承自UIImageView),我重新定义becomeFirstResponder以始终返回true。 我在- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier messageMaxWidth:(CGFloat)messageMaxWidth

中初始化了我的单元格
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier messageMaxWidth:(CGFloat)messageMaxWidth
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self) {
        self.messageMaxWidth = messageMaxWidth;
        self.backgroundColor = [UIColor clearColor];
        self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
        self.panGesture.delegate = self;
        [self addGestureRecognizer:self.panGesture];

        [self setInitialSizes];

        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOrientationWillChandeNote:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
    }

    return self;
}

    - (void)setInitialSizes
{
    if (self.containerView) {
        [self.containerView removeFromSuperview];
    }
    if (self.timeLabel) {
        [self.timeLabel removeFromSuperview];
    }

    self.userImageView = [[UIImageView alloc] init];
    self.userImageView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    self.textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, self.messageMaxWidth, 0)];
    self.timeLabel = [[UILabel alloc] init];
    self.mediaImageView = [[SOmessageImageView alloc] init];
    self.mediaOverlayView = [[UIView alloc] init];
    self.balloonImageView = [[SOmessageImageView alloc] init];

    self.balloonImageView.userInteractionEnabled = YES;

    if (!CGSizeEqualToSize(self.userImageViewSize, CGSizeZero)) {
        CGRect frame = self.userImageView.frame;
        frame.size = self.userImageViewSize;
        self.userImageView.frame = frame;
    }

    self.userImageView.contentMode = UIViewContentModeScaleAspectFill;
    self.userImageView.clipsToBounds = YES;
    self.userImageView.backgroundColor = [UIColor clearColor];
    self.userImageView.layer.cornerRadius = 5;

    if (!CGSizeEqualToSize(self.mediaImageViewSize, CGSizeZero)) {
        CGRect frame = self.mediaImageView.frame;
        frame.size = self.mediaImageViewSize;
        self.mediaImageView.frame = frame;
    }

    self.mediaImageView.contentMode = UIViewContentModeScaleAspectFill;
    self.mediaImageView.clipsToBounds = YES;
    self.mediaImageView.backgroundColor = [UIColor clearColor];
    self.mediaImageView.userInteractionEnabled = YES;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleMediaTapped:)];
    [self.mediaImageView addGestureRecognizer:tap];

    self.mediaOverlayView.backgroundColor = [UIColor clearColor];
    [self.mediaImageView addSubview:self.mediaOverlayView];

    self.textView.textColor = [UIColor whiteColor];
    self.textView.backgroundColor = [UIColor clearColor];
    [self.textView setTextContainerInset:UIEdgeInsetsZero];
    self.textView.textContainer.lineFragmentPadding = 0;

    [self hideSubViews];

    self.containerView = [[UIView alloc] initWithFrame:self.contentView.bounds];
    self.containerView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;

    [self.contentView addSubview:self.containerView];

    [self.containerView addSubview:self.balloonImageView];
    [self.containerView addSubview:self.textView];
    [self.containerView addSubview:self.mediaImageView];
    [self.containerView addSubview:self.userImageView];

    self.contentView.clipsToBounds = NO;
    self.clipsToBounds = NO;

    self.timeLabel.font = [UIFont fontWithName:@"AvenirNextCyr-Light" size:11];
    self.timeLabel.textColor = [UIColor grayColor];
    self.timeLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;

    UIImage *backgroundImage = [UIImage imageNamed:@"messagesDateBackground"];
    if (backgroundImage) {
        self.timeLabel.textColor = [UIColor whiteColor];
        if (self.backgroundImageView) {
            [self.backgroundImageView removeFromSuperview];
        }
        self.backgroundImageView = [[UIImageView alloc] initWithImage:[backgroundImage resizableImageWithCapInsets:UIEdgeInsetsMake(20, 20, 20, 20)]];
        self.backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
        [self.contentView addSubview:self.backgroundImageView];
    }

    [self.contentView addSubview:self.timeLabel];
}

请给我一些建议,如何解决这个奇怪的错误。

1 个答案:

答案 0 :(得分:2)

您的视图控制器可能有一个名为inputView的属性,它只是一个子视图,而不是inputView as UIResponder interface expects it to be

从iOS 8开始,他们检查UIResponder&#39; inputView是否没有父母。

相关问题