首页 文章

在UIView中捕获UIDeviceOrientationDidChangeNotification时UIInterfaceOrientation尚未更新

提问于
浏览
1

我正在开发一个开源库来提供类似iMessage的文本输入视图 - MessageComposerView(与问题相关) . 视图将像_2580750一样粘在键盘上,并随着文本一起增长,但键盘不会消失 .

旋转这个自定义UIView时,我最近遇到了一个令人抓狂的问题,只有在视图通过 initWithFrame 实例化后才出现 . 基本上,如果视图已通过 initWithFrame 实例化,则捕获到UIDeviceOrientationDidChangeNotification通知时,UIInterfaceOrientation和框架尚未更新 . 以下是实例化的两种方式 .

loadNibNamed

self.messageComposerView = [[NSBundle mainBundle] loadNibNamed:@"MessageComposerView" owner:nil options:nil][0];
self.messageComposerView.frame = CGRectMake(0,
                                            self.view.frame.size.height - self.messageComposerView.frame.size.height,
                                            self.messageComposerView.frame.size.width,
                                            self.messageComposerView.frame.size.height);

initWithFrame

self.messageComposerView = [[MessageComposerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-54, 320, 54)];

当通过 loadNibNamed 初始化并旋转到横向时,收到 UIDeviceOrientationDidChangeNotification 通知后:

  • UIDeviceOrientation = [[通知对象]方向] = UIInterfaceOrientationLandscapeLeft

  • UIInterfaceOrientation = [UIApplication sharedApplication] .statusBarOrientation = UIDeviceOrientationLandscapeRight

  • self.frame.size =(宽度= 480,身高= 90)

这里要注意的重要一点是界面和设备方向都是横向的,宽度已经改为横向宽度(在iPhone 6.1模拟器上测试) . 现在执行相同的测试,但使用 initWithFrame

  • UIDeviceOrientation = [[通知对象]方向] = UIDeviceOrientationLandscapeRight

  • UIInterfaceOrientation = [UIApplication sharedApplication] .statusBarOrientation = UIInterfaceOrientationPortrait

  • self.frame.size =(宽度= 320,身高= 54)

这次注意到界面方向仍然是纵向,并且框架宽度未更改为横向宽度 . 如果我在 setFrame:(CGRect)frame 方法中设置断点,我可以看到在捕获并处理了UIDeviceOrientationDidChangeNotification之后,帧被设置为Landscape帧 .

两种init方法都具有几乎相同的设置:

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.frame = frame;
        self.sendButton = [[UIButton alloc] initWithFrame:CGRectZero];
        self.messageTextView = [[UITextView alloc] initWithFrame:CGRectZero];
        [self setup];
        [self addSubview:self.sendButton];
        [self addSubview:self.messageTextView];

    }
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    [self setup];
}

setup 做必要的视图调整:

- (void)setup {
    self.backgroundColor = [UIColor lightGrayColor];
    self.autoresizesSubviews = YES;
    self.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth;
    self.userInteractionEnabled = YES;
    self.multipleTouchEnabled = NO;

    CGRect sendButtonFrame = self.bounds;
    sendButtonFrame.size.width = 50;
    sendButtonFrame.size.height = 34;
    sendButtonFrame.origin.x = self.frame.size.width - kComposerBackgroundRightPadding - sendButtonFrame.size.width;
    sendButtonFrame.origin.y = kComposerBackgroundRightPadding;
    self.sendButton.frame = sendButtonFrame;
    self.sendButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin;
    self.sendButton.layer.cornerRadius = 5;
    [self.sendButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [self.sendButton setTitleColor:[UIColor colorWithRed:210/255.0 green:210/255.0 blue:210/255.0 alpha:1.0] forState:UIControlStateHighlighted];
    [self.sendButton setTitleColor:[UIColor grayColor] forState:UIControlStateSelected];
    [self.sendButton setBackgroundColor:[UIColor orangeColor]];
    [self.sendButton setTitle:@"Send" forState:UIControlStateNormal];
    self.sendButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];


    CGRect messageTextViewFrame = self.bounds;
    messageTextViewFrame.origin.x = kComposerBackgroundLeftPadding;
    messageTextViewFrame.origin.y = kComposerBackgroundTopPadding;
    messageTextViewFrame.size.width = self.frame.size.width - kComposerBackgroundLeftPadding - kComposerTextViewButtonBetweenPadding - sendButtonFrame.size.width - kComposerBackgroundRightPadding;
    messageTextViewFrame.size.height = 34;
    self.messageTextView.frame = messageTextViewFrame;
    self.messageTextView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
    self.messageTextView.showsHorizontalScrollIndicator = NO;
    self.messageTextView.layer.cornerRadius = 5;
    self.messageTextView.font = [UIFont systemFontOfSize:14];
    self.messageTextView.delegate = self;

    [self addNotifications];
    [self resizeTextViewForText:@"" animated:NO];
}

所以我的问题是,为什么我的自定义UIView init通过 initWithFrame 仍然具有纵向框架和界面方向以及收到UIDeviceOrientationDidChangeNotification的时间 . 我使用此通知进行框架调整,并且需要将宽度更新为横向宽度 .

我在编程设置中丢失了'm hoping there is some kind of autorotation property that I'm,它隐藏在XIB中的某个地方,但是在没有找到解决方案的情况下,可能已经完成了十几个 UIDeviceOrientationDidChangeNotification stackoverflow帖子 .

1 回答

  • 4

    MessageComposerView看起来很整洁,感谢分享 .

    而不是听 UIDeviceOrientationDidChangeNotification ,你应该实现 layoutSubviews . 它被调用以响应旋转以及系统需要 UIView 重新定位其子视图的任何其他内容(https://stackoverflow.com/a/5330162/1181421) . 在那里你可以相对于 UIView 的框架定位子视图,你可以确定框架是正确的 .

相关问题