iOS-11粘贴菜单快速消失

时间:2018-02-20 17:14:30

标签: ios uitextfield ios11 copy-paste

我有一个奇怪的错误,我不知道如何开始调试。

"粘贴"当用户想要将某些内容粘贴到文本字段时出现的菜单只会持续几分之一秒,然后会再次自动消失。这适用于应用程序中的所有UITextField,无论是在iPhone本身还是在模拟器中。但它只发生在iOS 11上,我试过iOS 10.3.1模拟器,并且它工作正常(菜单保持不变)。

据我所知,我的应用程序中的字段没有什么特别之处。但我已经尝试了一个全新的项目,其中只有一个文本字段的应用程序,并且它工作正常。所以它必须是我的应用程序中导致它的东西。

欢迎任何想法。

出于调试目的,我已经为UIMenuControllerWillHideMenuNotification实现了一个通知处理程序,以便查看导致它的原因。发生这种情况时,这是堆栈跟踪:

#6  0x00000001147598f2 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#7  0x0000000112c5b6d6 in -[UIMenuController(UICalloutBarDelegateConformance) calloutBar:willStartAnimation:] ()
#8  0x0000000112c39c37 in -[UICalloutBar _fadeAfterCommand:] ()
#9  0x0000000112c12390 in -[UITextSelectionView removeFromSuperview] ()
#10 0x0000000112c13d30 in -[UITextSelectionView updateSelectionRectsIfNeeded] ()
#11 0x0000000112c13c90 in __51-[UITextSelectionView deferredUpdateSelectionRects]_block_invoke ()
#12 0x0000000115d93c07 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#13 0x0000000115d93b5e in __CFRunLoopDoObservers ()
#14 0x0000000115d77fe3 in __CFRunLoopRun ()
#15 0x0000000115d77889 in CFRunLoopRunSpecific ()
#16 0x0000000119dc19c6 in GSEventRunModal ()
#17 0x00000001125b25d6 in UIApplicationMain ()
#18 0x000000010dec3eb4 in main at /Users/rene/Projects/Flyskyhy/Flyskyhy/main.m:17
#19 0x00000001121e7d81 in start ()

编辑:如果我连续多次点击文本字段,则“粘贴”菜单会出现并且每次都会消失。我现在发现,失踪之间的时间总是精确的秒数。因此,某些计时器可能会导致此行为。

2 个答案:

答案 0 :(得分:0)

如果应用程序在粘贴菜单启动时写入任何UITextField,菜单将消失。如果它正在写入另一个完全不同的UIView,甚至在屏幕上看不到的UITextField,情况就是如此。在我的情况下,我有一个时钟字段,每秒更新一次。

我向Apple报告了这个错误。它至少在iOS版本V11.2中出现。 iOS-11之前的版本,如V10.3.1,没有显示错误。

作为解决方法,我现在使用以下UITextField子类而不是UITextField本身。菜单启动时,它会阻止对字段的更改。它似乎做了这个工作:

@implementation UITextFieldWrapper {
    bool pasteMenuActive;
    NSString *latestText;
}

- (void) setText:(NSString *)text
{
    if (!pasteMenuActive) {
        [super setText:text];
    } else {
        latestText = text;
    }
}

- (void) updatePasteMenu:(NSNotification *)notification
{
    pasteMenuActive = (notification.name == UIMenuControllerWillShowMenuNotification);
    if (!pasteMenuActive && latestText != nil) {
        self.text = latestText;
        latestText = nil;
    }
}

- (instancetype) initWithFrame:(CGRect)frame
{
    if (!(self = [super initWithFrame:frame])) {
        return nil;
    }
    pasteMenuActive = NO;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePasteMenu:) name:UIMenuControllerWillShowMenuNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updatePasteMenu:) name:UIMenuControllerWillHideMenuNotification object:nil];

    return self;
}

- (void) dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

@end

答案 1 :(得分:0)

我遇到了同样的问题,但是使用了自定义单元(collectionviewcell和tableviewcell)。我已经解决了在viewDidLoad中添加以下问题:

void select_year(int year_selected) {
    for(int i = 0 ; i < yearTemp.length ++i) {
        if((i* 2) + 1 > highLowTemp.length)
            throw Exception("bad data"); // probably handle this better
        int year = yearTemp[i]
        if(year_selected == year) {
            int low = highLowTemp[i * 2]
            int high = highLowTemp[(i * 2) + 1]
            // this is the high and low for the year_selected
            // do stuff with it
            // edit: break from here when you are done
        }
    }
}