Ios 当UIView中捕获UIDeviceOrientationIDChangeNotification时,UIInterfaceOrientation尚未更新

Ios 当UIView中捕获UIDeviceOrientationIDChangeNotification时,UIInterfaceOrientation尚未更新,ios,objective-c,uiview,rotation,autoresizingmask,Ios,Objective C,Uiview,Rotation,Autoresizingmask,我正在开发一个开源库,以提供类似于iMessage的文本输入视图——与问题相关。视图将像inputAccessoryView一样附着在键盘上,并随着文本的增长而增长,但不会在键盘消失时消失 我最近在旋转这个自定义UIView时遇到了一个令人恼火的问题,该视图只有通过initWithFrame实例化后才会出现。基本上,当通过initWithFrame实例化视图时,捕获到UIDeviceOrientationIDChangeNotification通知时,UIInterfaceOrientation

我正在开发一个开源库,以提供类似于iMessage的文本输入视图——与问题相关。视图将像inputAccessoryView一样附着在键盘上,并随着文本的增长而增长,但不会在键盘消失时消失

我最近在旋转这个自定义UIView时遇到了一个令人恼火的问题,该视图只有通过initWithFrame实例化后才会出现。基本上,当通过initWithFrame实例化视图时,捕获到UIDeviceOrientationIDChangeNotification通知时,UIInterfaceOrientation和frame尚未更新。这里有两种实例化方法

加载名为:

initWithFrame:

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

UIDeviceOrientation=[[notification object]orientation]=UIInterfaceOrientation和scapeLeft UIInterfaceOrientation=[UIApplication sharedApplication].statusBarOrientation=UIDeviceOrientation和SCAPERight self.frame.size=宽度=480,高度=90 这里需要注意的重要一点是,界面和设备方向都是横向的,宽度已经在iPhone 6.1模拟器上更改为横向宽度测试。现在执行相同的测试,但使用initWithFrame:

UIDeviceOrientation=[[notification object]orientation]=UIDeviceOrientation和scapeRight UIInterfaceOrientation=[UIApplication sharedApplication].statusBarOrientation=UIInterfaceOrientation纵向 self.frame.size=宽度=320,高度=54 这一次请注意,界面方向仍然是纵向的,并且帧宽度没有更改为横向宽度。如果我在setFrame:CGRectframe方法中设置断点,我可以看到在捕获并处理UIDeviceOrientationIDChangeNotification之后,该帧被设置为横向帧

两种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];
}
通过安装程序进行必要的视图调整:

- (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仍然具有纵向框架和接口方向,以及接收UIDeviceOrientationIDChangeNotification的时间。我使用此通知进行帧调整,需要宽度已更新为横向宽度


我希望有某种自转属性,我在程序设置中丢失了,它埋在XIB的某个地方,但就是找不到。我可能已经浏览了十几篇UIDeviceOrientationIDChangeNotification stackoverflow帖子,但没有找到解决方案。

MessageComposer视图看起来不错,谢谢分享


您应该实现LayoutSubview,而不是侦听UIDeviceOrientationIDChangeNotification。调用它是为了响应旋转和系统需要UIView重新定位其子视图的任何其他操作。在那里,您可以相对于UIView的框架定位子视图,并且可以确保框架是正确的。

MessageComposer视图看起来很整洁,谢谢分享


您应该实现LayoutSubview,而不是侦听UIDeviceOrientationIDChangeNotification。调用它是为了响应旋转和系统需要UIView重新定位其子视图的任何其他操作。在那里,您可以相对于UIView的框架定位子视图,并且可以确保框架是正确的。

您可以删除self.frame=frame;在初始化代码中输入一行。对super的调用应该已经完成了。您可以删除self.frame=frame;在初始化代码中输入一行。打电话给super应该已经做到了。我非常感谢你。我一直非常专注于解决当捕获到UIDeviceOrientationIDChangeNotification时为什么框架还没有调整大小,以至于我完全忽略了在其他地方重新配置的可能性。我仍然很好奇为什么会出现这个问题,但从我在UIDeviceOrientation更改的确切时刻期待UIInterfaceOrientation更改这一事实来看,我认为我的方法从一开始就是有缺陷的。我非常感谢你。我一直非常专注于解决当捕获到UIDeviceOrientationIDChangeNotification时为什么框架还没有调整大小,以至于我完全忽略了在其他地方重新配置的可能性。我仍然很好奇为什么会出现这个问题,但从我在UIDeviceOrientation更改的确切时刻期待UIInterfaceOrientation更改这一事实来看,我认为我的方法从一开始就是有缺陷的。
- (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];
}
- (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];
}